有四种类型;
单源: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