【深搜】【加法与乘法原理】【120817测试】【JSOI2007夏令营考试】题3:游览(c.pas/c/cpp)
2012-08-21 09:21
246 查看
题3:游览(c.???)
顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了!
你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开。可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是你还想乘船从桃花岛东头的码头回到西头,再玩一遍,但是桃花岛有个规矩:你可以游览无数遍,但是每次游玩的路线不能完全一样。
我们把桃花岛抽象成了一个图,共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取余)。
输入样例:
3 4 1 3 7
1 2 5
2 3 7
2 3 10
1 3 15
输出样例:
56
样例说明:
共有3条路径可以从点1到点3,分别是1-2-3,1-2-3,1-3。
时间计算为:
(5+7)+7 +(5+10)+7 +(15)=56
这一题如果暴搜的话能的40分
加上乘法原理和加法原理就能AC
根据输入数据,我们知道可能会出现重边,那么矩阵就不能用了,就要用到链表
•加法原理和乘法原理
![](http://pic002.cnblogs.com/images/2012/418409/2012082109494737.jpg)
•V1->v10的不同路径总长度=
–(v1->v8->v10)+(v1->v9->v10)+总方法数*t0
•设v1->vi的所有不同路径方法数为count(i)
•设v1->vi的所有不同路径径长度和为sumdis(i)
•Sumdis(10) =Sumdis(8)+5*count(8)+sumdis(9)+2*count(9)
•Sumdis(i)= ∑ sumdis(j)+map(j,i)*count(j) (j是i的前趋)
•Count(i)= ∑ count(j) (j是i的前趋)
•按拓扑序维护出sumdis(i)和count(i)即可求出总代价=Sumdis(10)+count(10)*t0
•实现,记忆化搜索
剩下的就是代码实现了
C++ Code
顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了!
你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开。可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是你还想乘船从桃花岛东头的码头回到西头,再玩一遍,但是桃花岛有个规矩:你可以游览无数遍,但是每次游玩的路线不能完全一样。
我们把桃花岛抽象成了一个图,共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取余)。
输入样例:
3 4 1 3 7
1 2 5
2 3 7
2 3 10
1 3 15
输出样例:
56
样例说明:
共有3条路径可以从点1到点3,分别是1-2-3,1-2-3,1-3。
时间计算为:
(5+7)+7 +(5+10)+7 +(15)=56
这一题如果暴搜的话能的40分
加上乘法原理和加法原理就能AC
根据输入数据,我们知道可能会出现重边,那么矩阵就不能用了,就要用到链表
•加法原理和乘法原理
![](http://pic002.cnblogs.com/images/2012/418409/2012082109494737.jpg)
•V1->v10的不同路径总长度=
–(v1->v8->v10)+(v1->v9->v10)+总方法数*t0
•设v1->vi的所有不同路径方法数为count(i)
•设v1->vi的所有不同路径径长度和为sumdis(i)
•Sumdis(10) =Sumdis(8)+5*count(8)+sumdis(9)+2*count(9)
•Sumdis(i)= ∑ sumdis(j)+map(j,i)*count(j) (j是i的前趋)
•Count(i)= ∑ count(j) (j是i的前趋)
•按拓扑序维护出sumdis(i)和count(i)即可求出总代价=Sumdis(10)+count(10)*t0
•实现,记忆化搜索
剩下的就是代码实现了
C++ Code
#include<cstdio> #include<list> using namespace std; #define MAXN 10000+10 #define mod 10000 typedef struct {int pos,z;}tnode; list <tnode> first[MAXN]; int n,m,s,t,t0; int sum[MAXN],count[MAXN]; bool h[MAXN]; void dfs(int x) { if(h[x])return; if(x==s) { count[x]=1; sum[x]=0; return; } h[x]=true; list<tnode> pnode=first[x]; tnode p; int y,z; int counti=0,sumi=0; while (!pnode.empty()) { p=pnode.front(); y=p.pos;z=p.z; dfs(y); counti+=count[y]%mod; sumi+=(sum[y]%mod+(z*count[y])%mod)%mod; pnode.pop_front(); } sum[x]=sumi; count[x]=counti; } int main() { freopen("c.in","r",stdin); freopen("c.out","w",stdout); scanf("%d%d%d%d%d",&n,&m,&s,&t,&t0); int i,j,x,y,z; tnode p; for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); p.pos=x;p.z=z; first[y].push_back(p); } dfs(t); int total=sum[t]%mod+((t0%mod)*(count[t]%mod))%mod; printf("%d",(mod+(total-t0)%mod)%mod); return 0; }
![](http://pic002.cnblogs.com/images/2012/418409/2012082109504570.jpg)
相关文章推荐
- 【深搜】【加法与乘法原理】【JSOI2007夏令营考试】游览(c.pas/c/cpp)
- 【动规】【120817测试】【JSOI2007夏令营考试】题2:考验(b.pas/c/cpp)
- 【遍历染色】【120817测试】【JSOI2007夏令营考试】题1:入门(a.pas/c/cpp)
- 【动规】【JSOI2007夏令营考试】考验(b.pas/c/cpp)
- 【120817测试】JSOI2007夏令营考试(A层次)
- 【遍历染色】【JSOI2007夏令营考试】入门(a.pas/c/cpp)
- 【记忆化】【120819测试】【记忆化搜索专题】能量项链(energy.pas/c/cpp)
- 【记忆化】【120819测试】【记忆化搜索专题】恶魔城(satanic.pas/c/cpp)
- 【记忆化】【120819测试】【记忆化搜索专题】滑雪(ski.pas/c/cpp)
- 【动规递推】【120820测试】旅行(travel.pas/c/cpp)
- 1030: [JSOI2007]文本生成器
- bzoj[JSOI2007]字符加密Cipher
- 【算法导论】2-1-4二进制整数加法.cpp
- 部署 OCS 2007 R2之一:准备架构和测试环境 推荐
- bzoj1030 [JSOI2007]文本生成器
- 【BFS】英雄(hero.cpp/pas)
- 【BZOJ1028】【JSOI2007】麻将 暴力
- 【bzoj1029】[JSOI2007]建筑抢修
- 试题三:古代人的难题( puzzle.pas/c/cpp) 斐波那契数列
- bzoj 1031: [JSOI2007]字符加密Cipher 后缀数组