有四种类型;
单源:dij,spfa,bellman-ford
多源:floyd
dij有两种:
一个复杂度为n^2,一个复杂度是m*logn
畅通工程续
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
#include <stdio.h>//n^2 #include <stdlib.h> #include <string.h> #define inf 0x3f3f3f3f using namespace std; const int maxn=220; int w[maxn][maxn],d[maxn]; bool vis[maxn]; int n,m; void dijkstra(int s) { memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) d[i]=inf; d[s]=0; for(int i=0;i<n;i++) { int x=-1,y=inf; for(int j=0;j<n;j++) { if(vis[j]==0&&d[j]<=y) y=d[x=j]; } if(x==-1) continue; vis[x]=1; for(int j=0;j<n;j++) { if(!vis[j]&&d[j]>d[x]+w[x][j]) d[j]=d[x]+w[x][j]; } } } int main() { while(scanf("%d %d",&n,&m)!=EOF) { for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { if(i==j) w[i][j]=0; else w[i][j]=inf; } } for(int i=0;i<m;i++) { int a,b,x; scanf("%d%d%d",&a,&b,&x); if(w[a][b]>x) w[a][b]=w[b][a]=x; } int s,t; scanf("%d%d",&s,&t); dijkstra(s); if(d[t]>=inf) printf("-1\n"); else printf("%d\n",d[t]); } return 0; }
#include <stdio.h>//mlogn #include <stdlib.h> #include <string.h> #include <queue> #include <vector> #define inf 0x3f3f3f3f using namespace std; const int maxn=1100; int d[maxn],n,m; bool vis[maxn]; struct edge { int from,to,dist; edge(int from,int to,int dist):from(from),to(to),dist(dist){} }; struct heapnode { int d,u; heapnode(int d,int u) : d(d),u(u) {} bool operator<(const heapnode &a) const{ return a.d<d; } }; queue<edge>q[maxn]; void dijkstra(int s) { priority_queue<heapnode>que; for(int i=0;i<=n;i++) d[i]=inf; d[s]=0; memset(vis,0,sizeof(vis)); que.push(heapnode(0,s)); while(!que.empty()) { heapnode x=que.top();que.pop(); int u=x.u; if(vis[u]) continue; vis[u]=1; while(!q[u].empty()) { edge e=q[u].front(); q[u].pop(); if(d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; que.push(heapnode(d[e.to],e.to)); } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<n;i++) while(!q[i].empty()) q[i].pop(); for(int i=0;i<m;i++) { int a,b,x; scanf("%d%d%d",&a,&b,&x); q[a].push(edge(a,b,x)); q[b].push(edge(b,a,x)); } int s,t; scanf("%d%d",&s,&t); dijkstra(s); if(d[t]>=inf) printf("-1\n"); else printf("%d\n",d[t]); } return 0; }
#include <stdio.h>//mlogn #include <stdlib.h> #include <string.h> #include <queue> #include <vector> #define inf 0x3f3f3f3f using namespace std; const int maxn=1100; int d[maxn],n,m; bool vis[maxn]; struct edge { int from,to,dist; edge(int from,int to,int dist):from(from),to(to),dist(dist){} }; struct heapnode { int d,u; heapnode(int d,int u) : d(d),u(u) {} bool operator<(const heapnode &a) const{ return a.d<d; } }; vector<edge> vec; vector<int> g[maxn]; void dijkstra(int s) { priority_queue<heapnode>que; for(int i=0;i<=n;i++) d[i]=inf; d[s]=0; memset(vis,0,sizeof(vis)); que.push(heapnode(0,s)); while(!que.empty()) { heapnode x=que.top();que.pop(); int u=x.u; if(vis[u]) continue; vis[u]=1; for(int i=0;i<g[u].size();i++) { edge &e=vec[g[u][i]]; if(d[e.to]>d[u]+e.dist) { d[e.to]=d[u]+e.dist; que.push(heapnode(d[e.to],e.to)); } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<=n;i++) g[i].clear(); vec.clear(); for(int i=0;i<m;i++) { int a,b,x; scanf("%d%d%d",&a,&b,&x); vec.push_back(edge(a,b,x)); int c=vec.size(); g[a].push_back(c-1); vec.push_back(edge(b,a,x)); c=vec.size(); g[b].push_back(c-1); } int s,t; scanf("%d%d",&s,&t); dijkstra(s); if(d[t]>=inf) printf("-1\n"); else printf("%d\n",d[t]); } return 0; }
C - find the longest of the shortest
InputEach case there are two numbers in the first row, N and M, separated by a single space, the number of towns,and the number of roads between the towns. 1 ≤ N ≤ 1000, 1 ≤ M ≤ N*(N-1)/2. The cities are markedwith numbers from 1 to N, Mirko is located in city 1, and Marica in city N.
In the next M lines are three numbers A, B and V, separated by commas. 1 ≤ A,B ≤ N, 1 ≤ V ≤ 1000.Those numbers mean that there is a two-way road between cities A and B, and that it is crossable in V minutes.OutputIn the first line of the output file write the maximum time in minutes, it could take Marica to come to Mirko.Sample Input
5 6 1 2 4 1 3 3 2 3 1 2 4 4 2 5 7 4 5 1 6 7 1 2 1 2 3 4 3 4 4 4 6 4 1 5 5 2 5 2 5 6 5 5 7 1 2 8 1 4 10 2 3 9 2 4 10 2 5 1 3 4 7 3 5 10
Sample Output
11 13 27
这个和之前差不多,有一点点区别,就是让你求出最短路,然后在最短路里面枚举每一边断了,这个最坏的情况用的时间。
这个用邻接矩阵写的,用队列的太麻烦
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <algorithm> #define inf 0x3f3f3f3f using namespace std; const int maxn=1100; int w[maxn][maxn]; int d[maxn]; int path[maxn]; bool flag,vis[maxn]; int n,m; void dijkstra(int s) { for(int i=0;i<=n;i++) { d[i]=inf; vis[i]=0; } d[s]=0; for(int i=1;i<=n;i++) { int x,m=inf; for(int j=1;j<=n;j++) if(!vis[j]&&d[j]<m) m=d[x=j]; vis[x]=1; for(int j=1;j<=n;j++) { if(d[j]>d[x]+w[x][j]) { d[j]=d[x]+w[x][j]; if(!flag) path[j]=x; } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) w[i][j]=0; else w[i][j]=inf; } } for(int i=1;i<=m;i++) { int a,b,x; scanf("%d%d%d",&a,&b,&x); w[a][b]=x; w[b][a]=x; } flag=0; dijkstra(1); // printf("%d\n",d[n]); flag=1; int tmp,ans=d[n]; for(int i=n;i>1;i=path[i]) { tmp=w[path[i]][i]; w[path[i]][i]=inf; dijkstra(1); w[path[i]][i]=tmp; if(d[n]>=inf) continue; ans=max(ans,d[n]); // printf("%d\n",i); } printf("%d\n",ans); } return 0; }
Input
Output
Sample Input
2 0 0 3 4 3 17 4 19 4 18 5 0
Sample Output
Scenario #1 Frog Distance = 5.000 Scenario #2 Frog Distance = 1.414
这个题目有点特别,要结合贪心,在d[i]的i的取值的时候要注意不是直接取求出到达i的最短路径长度,而是,从1号位置到这个位置的最长边的最小值。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <queue> #include <algorithm> #include <math.h> #define inf 0x3f3f3f3f using namespace std; const int maxn=250; int n; double d[maxn]; bool vis[maxn]; double w[maxn][maxn]; struct node { double x,y; node(double x=0,double y=0):x(x),y(y){} }exa[maxn]; void dijkstra() { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) d[i]=w[1][i]; for(int i=1;i<=n;i++) { int x=-1; double m=inf; for(int j=1;j<=n;j++) { if(!vis[j]&&d[j]<m) m=d[x=j]; } if(x!=-1) { vis[x]=1; for(int j=1;j<=n;j++) { if(!vis[j]&&d[j]>max(d[x],w[x][j])) d[j]=max(d[x],w[x][j]); } } } } int main() { int cnt=0; while(scanf("%d\n",&n)!=EOF&&n) { for(int i=1;i<=n;i++) { scanf("%lf%lf",&exa[i].x,&exa[i].y); } for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { w[i][j]=w[j][i]=sqrt((exa[i].x-exa[j].x)*(exa[i].x-exa[j].x)+(exa[i].y-exa[j].y)*(exa[i].y-exa[j].y)); } } dijkstra(); printf("Scenario #%d\nFrog Distance = %.3lf\n\n",++cnt,d[2]); } return 0; }
原文:https://www.cnblogs.com/EchoZQN/p/10427625.html