JSOI2007夏令营考试游览

Posted adelalove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSOI2007夏令营考试游览相关的知识,希望对你有一定的参考价值。

题目描述

顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了!

你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开。可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是你还想乘船从桃花岛东头的码头回到西头,再玩一遍,但是桃花岛有个规矩:你可以游览无数遍,但是每次游玩的路线不能完全一样。

我们把桃花岛抽象成了一个图,共n个点代表路的相交处,m条边表示路,边是有向的(只能按照边的方向行走),且可能有连接相同两点的边。输入保证这个图没有环,而且从西头到东头至少存在一条路线。两条路线被认为是不同的当且仅当它们所经过的路不完全相同。

你的任务是:把所有不同的路线游览完一共要花多少时间?

输入输出格式

输入格式:

 

第1行为5个整数:n、m、s、t、t0,分别表示点数,边数,岛西头的编号,岛东头的编号(编号是从1到n)和你乘船从岛东头到西头一次的时间。

以下m行,每行3个整数:x、y、t,表示从点x到点y有一条行走耗时为t的路。

每一行的多个数据之间用一个空格隔开,且:2<=n<=10000; 1<=m<=50000;t<=10000;t0<=10000

 

输出格式:

 

假设总耗时为total,则输出total mod 10000的值(total对10000取余)。

 

输入输出样例

输入样例#1: 
3 4 1 3 7
1 2 5
2 3 7
2 3 10
1 3 15
输出样例#1: 
56

说明

【样例说明】

共有3条路径可以从点1到点3,分别是1-2-3,1-2-3,1-3。

时间计算为:

(5+7)+7 +(5+10)+7 +(15)=56

 

解:
暴力:
爆搜所有的路线,40分


正解:加法原理+乘法原理


设sum[i]为从起点出发到达i的方案数
len[i]为为从起点出发到达i的路径总和
考虑一条边i -> j ,花费时间为t
那么则有:
len[j]=len[j]+len[i]+t*sum[i];
sum[j]=sum[j]+sum[i]
对于起点S:sum[S]=1;

注意题目中给的性质:
“输入保证这个图没有环,而且从西头到东头至少存在一条路线”
于是我们可以利用拓扑排序来进行这一工作,得到
sum[i]和len[i].
我们也可以建反向边,从T开始出发去找,进行DFS,
从而得到sum[i]和len[i]

代码:

1.拓扑排序做法

 

技术分享图片
 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<cmath>
 8 #define ll long long
 9 #define DB double
10 #define mod 10000
11 #define eps 1e-3
12 #define inf 2147483600
13 using namespace std;
14 inline int read()
15 {
16     int x=0,w=1;char ch=getchar();
17     while(ch<0 || ch>9){if(ch==-) w=-1;ch=getchar();}
18     while(ch>=0 && ch<=9) x=(x<<3)+(x<<1)+ch-0,ch=getchar();
19     return x*w;
20 }
21 const int N=1e6+10;
22 struct node{
23     int u,v,c,ne;
24 }e[N];
25 int h[N],tot,v[N],d[N];
26 void add(int u,int v,int c)
27 {
28     d[v]++;
29     tot++;e[tot]=(node){u,v,c,h[u]};h[u]=tot;
30 }
31 int n,m,S,T,t0,sum[N],len[N];
32 queue<int>q;
33 void tuopu()
34 {
35     sum[S]=1;
36     for(int i=1;i<=n;++i) 
37      if(d[i]==0) q.push(i);
38     while(!q.empty())
39     {
40         int ff=q.front();q.pop();
41         for(int i=h[ff];i;i=e[i].ne)
42         {
43             int rr=e[i].v;
44             d[rr]--;
45             sum[rr]=(sum[rr]+sum[ff])%mod;
46             len[rr]=(len[rr]+len[ff]+e[i].c*sum[ff]%mod)%mod;
47             if(d[rr]==0) q.push(rr);
48         }
49     }
50 }
51 int main()
52 {
53     n=read();m=read();S=read();T=read();t0=read();
54     for(int i=1;i<=m;++i)
55     {
56         int x,y,z;x=read();y=read();z=read();
57         add(x,y,z);
58     }
59     tuopu();
60     ll ans=0;
61     ans=(len[T]+(sum[T]-1)*t0%mod)%mod;
62     printf("%lld",(ans+mod)%mod);
63     return 0;
64 }
View Code

 

2.DFS做法

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<map>
 7 #include<queue>
 8 #define mod 10000
 9 #define inf 336860180
10 #define PI 3.1415926
11 #define ll long long
12 using namespace std;
13 int n,m,s,t,t0,h[100000],tot,ans,sum[100000],len[100000];
14 struct po{int v,c,last;}a[500000];
15 void add(int u,int v,int c)
16 {
17     tot++;
18     a[tot].v=v;a[tot].c=c;
19     a[tot].last=h[u];h[u]=tot;
20 }
21 bool v[1000000];
22 void dfs(int x)
23 {
24     if(v[x]) return ;
25     v[x]=1;
26     if(x==s)
27     {
28         sum[x]=1;len[x]=0;
29          return;
30     }
31     int sumx=0,lenx=0;
32     for(int i=h[x];i;i=a[i].last)
33     {
34      int to=a[i].v;
35      dfs(to);
36      lenx=(lenx+a[i].c*sum[to]+len[to])%mod;
37      sumx=(sumx+sum[to])%mod;
38     }
39     sum[x]=sumx;len[x]=lenx;
40 }
41 int main()
42 {
43     scanf("%d%d%d%d%d",&n,&m,&s,&t,&t0);
44     for(int i=1;i<=m;i++)
45     {
46      int x,y,t;scanf("%d%d%d",&x,&y,&t);
47      add(y,x,t);    
48     }
49     dfs(t);
50     ans=(mod+len[t]+(sum[t]-1)*t0%mod)%mod;
51     cout<<ans;
52     return 0;
53 }
View Code

(?′?‵?)I L???????

 


















以上是关于JSOI2007夏令营考试游览的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1030: [JSOI2007]文本生成器

bzoj1030 [JSOI2007]文本生成器

2015 JSOI冬令营训练 彩色格子 题解

JSOI2007 文本生成器

JSOI2018冬令营游记&总结(迁移自洛谷博客)

「JSOI2007」建筑抢修