HDU 1874 畅通工程续(最短路/spfa Dijkstra 邻接矩阵+邻接表)
2016-07-10 21:46
423 查看
题目链接: 传送门
畅通工程续
Time Limit: 1000MS Memory Limit: 65536K
Description
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M (0<N<200,0<M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B<N,A!=B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T<N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
Sample Input
3 3 0 1 1 0 2 3 1 2 1 0 2 3 1 0 1 1 1 2
Sample Output
2 -1
思路
spfa+邻接表
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; struct Edge{ int u,v,w,next; }; Edge edge[2005]; const int INF = 0x3f3f3f3f; int dis[2005]; int head[2005]; int vis[2005]; void spfa(int s) { memset(dis,0x3f3f3f3f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int>que; dis[s] = 0; vis[s] = 1; que.push(s); while (!que.empty()) { int curval = que.front(); que.pop(); vis[curval] = 0; for (int i = head[curval];i != -1;i = edge[i].next) { if (dis[curval]+edge[i].w < dis[edge[i].v]) { dis[edge[i].v] = dis[curval] + edge[i].w; if (!vis[edge[i].v]) { vis[edge[i].v] = 1; que.push(edge[i].v); } } } } } int main() { int N,M; while (~scanf("%d%d",&N,&M)) { int u,v,w,s,t; memset(head,-1,sizeof(head)); for (int i = 0;i < 2*M;i+=2) { scanf("%d%d%d",&u,&v,&w); edge[i].u = u;edge[i].v = v;edge[i].w = w;edge[i].next = head[u];head[u] = i; edge[i+1].u = v;edge[i+1].v = u;edge[i+1].w = w;edge[i+1].next = head[v];head[v] = i+1; } scanf("%d%d",&s,&t); spfa(s); printf("%d\n",dis[t] == INF?-1:dis[t]); } return 0; }
spfa+邻接矩阵
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> using namespace std; const int INF = 0x3f3f3f3f; const int MAX = 1005; int edge[MAX][MAX]; void spfa(int s,int n,int t) { int dis[MAX]; bool vis[MAX]; memset(dis,0x3f,sizeof(dis)); memset(vis,false,sizeof(vis)); queue<int>que; dis[s] = 0; que.push(s); vis[s] = true; while (!que.empty()) { int curval = que.front(); que.pop(); vis[curval] = false; for (int i = 0;i < n;i++) { if (dis[curval] < dis[i] - edge[curval][i]) { dis[i] = dis[curval] + edge[curval][i]; if (!vis[i]) { que.push(i); vis[i] = true; } } } } printf("%d\n",dis[t] == INF?-1:dis[t]); } int main() { int N,M; while (~scanf("%d%d",&N,&M)) { int u,v,w,S,T; for (int i = 0;i < N;i++) { for (int j = 0;j < i;j++) { if (i == j) edge[i][j] = 0; else edge[i][j] = edge[j][i] = INF; } } for (int i =0;i < M;i++) { scanf("%d%d%d",&u,&v,&w); edge[u][v] = edge[v][u] = min(w,edge[u][v]); } scanf("%d%d",&S,&T); spfa(S,N,T); } return 0; }
Dijkstra+邻接矩阵
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAX = 205; const int INF = 0x3f3f3f3f; int edge[MAX][MAX]; void Dijkstra(int s,int t,int n) { bool vis[MAX]; int dis[MAX]; int min,pos; memset(vis,false,sizeof(vis)); for (int i = 0;i < n;i++) { dis[i] = edge[s][i]; } for (int i = 1;i < n;i++) { min = INF; for (int j = 0;j < n;j++) { if (dis[j] < min && !vis[j]) { pos = j; min = dis[j]; } } vis[pos] = true; for (int j = 0;j < n;j++) { if (dis[pos] + edge[pos][j] < dis[j]) { dis[j] = dis[pos] + edge[pos][j]; } } } printf("%d\n",dis[t] == INF?-1:dis[t]); } int main() { int N,M,S,T; while (~scanf("%d%d",&N,&M)) { int u,v,w; for (int i = 0;i < N;i++) { for (int j = 0;j < i;j++) { if (i == j)edge[i][j] = edge[j][i] = 0; else edge[i][j] = edge[j][i] = INF; } } for (int i = 0;i < M;i++) { scanf("%d%d%d",&u,&v,&w); if (w < edge[u][v]) { edge[u][v] = edge[v][u] = w; } } scanf("%d%d",&S,&T); Dijkstra(S,T,N); } return 0; }
相关文章推荐
- 【Python学习笔记】函数式编程:偏函数
- ubuntu git利用ssh进行push(无需用户名&&密码)
- 嵌入式 Linux网络编程(二)——TCP编程模型
- UVa 1347
- GIT 存储格式与运用
- mysql的mvcc(多版本并发控制)
- JSP的内置对象
- java.lang.ClassNotFoundException
- Python下用List对员工信息表进行模糊匹配
- 指令流水线的吞吐率
- 在gridview上显式系统联系人的信息
- shell编写简单的CGI脚本
- Android开源项目 优秀项目
- HTML5中新增的元素
- window.location.hash属性介绍
- encode_utf8 把字符编码成字节 微信例子
- MATLAB数学建模(3)-非线性规划
- hdu 2586 How far away
- 补充网站的盈利
- 两个链表的交叉