hduoj 13375 Flowery Trails
2015-08-10 14:03
288 查看
题目叙述:
给定P个点,T条边。约定起点是第0个点,终点是第P-1的点,求从起点到终点的所有最短路径的边的和乘以二。
难点:
有时候,存在多条路径共享多条边,那么在求和时,就只能加上不共享的边,而不是方案数乘以最短路径的长度。
关键:
标记走过的路径。
代码如下(具体有相应的注释):
给定P个点,T条边。约定起点是第0个点,终点是第P-1的点,求从起点到终点的所有最短路径的边的和乘以二。
难点:
有时候,存在多条路径共享多条边,那么在求和时,就只能加上不共享的边,而不是方案数乘以最短路径的长度。
关键:
标记走过的路径。
代码如下(具体有相应的注释):
#include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #include <queue> #include <cmath> using namespace std; #define INF 0x3f3f3f3f #define ll __int64 const int maxn=10005; ll sum; struct Edge { Edge(int a,int b):to(a),wi(b){} int to,wi; }; vector<Edge> map[maxn]; vector<int> qian[maxn]; vector<int> path[maxn]; int dis[maxn],P; bool vis[maxn],vis1[maxn]; void SPFA(int start) { queue<int> que; // while(!que.empty()) que.pop(); memset(vis,0,sizeof(vis)); memset(dis,0x3f,sizeof(dis)); que.push(start); vis[start]=1; dis[start]=0; while(!que.empty()) { int top; top=que.front(); que.pop(); vis[top]=0; for(int i=0;i<map[top].size();i++) { int x=map[top][i].to,wi=map[top][i].wi; if(dis[x]>dis[top]+wi)//更新最短权值 { dis[x]=dis[top]+wi; if(!vis[x]) { vis[x]=1; que.push(x); } qian[x].clear(); qian[x].push_back(top);//记录到该点的最短路径的前一个点 path[x].clear(); path[x].push_back(i);//记录该点容器的第几条边 }else if(dis[x]==dis[top]+wi)//如果有多条路径就记录多次 { qian[x].push_back(top); path[x].push_back(i); } } } } void search(int last) { if(vis1[last]) { return;} vis1[last]=1;//保证不重复计算同一条路径 for(int i=0;i<qian[last].size();i++) { int u=qian[last][i]; int v=path[last][i]; sum+=map[u][v].wi; search(u); } } int main() { // freopen("s","r",stdin); int T; while(scanf("%d%d",&P,&T)!=EOF) { sum=0; for(int i=0;i<P;i++)//每次输入点和边,就把之前的容器全部清除 { map[i].clear(); qian[i].clear(); path[i].clear(); } for(int i=0;i<T;i++) { int p1,p2,l; scanf("%d%d%d",&p1,&p2,&l);//输入边的两点以及权值 if(p1==p2) { continue;}//如果是自环,就没有必要记录,因为最短路径肯定没有自环 Edge x1(p2,l),x2(p1,l);//构建图 map[p1].push_back(x1); map[p2].push_back(x2); } SPFA(0);//通过SPFA算出单源最短路径,并同时通过qian和path记录路径 memset(vis1,0,sizeof(vis1)); search(P-1);//求和 printf("%I64d\n",sum*2);//和的两倍 } return 0; }
相关文章推荐
- grails 常用技巧
- 矩阵hash + KMP - UVA 12886 The Big Painting
- SparkException: Failed to get broadcast (TorrentBroadcast)
- 1086.Tree Traversals Again
- Command /bin/sh failed with exit code 64问题排查
- [ Yum_Faq ] unpacking of archive failed on file XXX: cpio: rename
- 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为参数,泛型函数
- windows下桌面共享(cp:http://jingyan.baidu.com/article/fea4511a455f17f7bb9125d7.html)
- hdu 5361 In Touch 题目特点+优先队列的dijikstra 2015 Multi-University Training Contest 6
- [转]UltraISO制作U盘启动盘安装Win7/9/10系统攻略
- 杭电2124Repair the Wall
- A naive AI for TicTacToe
- Regionals 2009 >> Asia - Hsinchu UVALIVE, 4528 Schedule Pairs of Jobs - 搜索回溯
- hdu1702(ACboy needs your help again!) 在杭电又遇坑了
- 2015 Multi-University Training Contest-6 Key Set
- 2015 Multi-University Training Contest-5 MZL's chemistry
- 2015 Multi-University Training Contest-5 MZL's xor
- hdu1022(Train Problem I)----- 典型栈类题目
- failed to load the jni shared library jvm
- 多图细数TurboMail邮件系统丰富的用户权限管理