poj 3268 (两种方法)
这题的意思是要求最短距离中的最大值。一看题目,要求来回的距离,就想到用floyd。看了看数据,觉得不行呀。看了discuss,果然floyd过不了的。看别人推荐的好的方法:1.Dijkstra;2.SPFA.不过两个方法都要用到矩阵的转置。这样才能求到来回的最短路径。第一次是求X到其它各点的最短距离(也即回来的距离),转置后,再次求X到其它点的距离,就可以得到其它各点到X的最短距离。很巧妙! 再次练习Dijkstra方法。要想掌握一个算法,那就必须多次敲!多次!多次!
Dijkstra:
#include <iostream> #include <fstream> using namespace std; #define MAXN 1005 #define INF 0x7fffff int map[MAXN][MAXN]; int dist[MAXN]; bool vist[MAXN]; int N,X,M; void Dij() { int i,j; for(i=0; i<=N; i++) { dist[i]=INF; } memset(vist,false,sizeof(vist)); dist[X]=0; //初始化节点 for(i=1; i<N; i++) { int min=INF,k=0; for(j=1; j<=N; j++) //遍历源点到所有顶点的距离,选出最小的 { if(!vist[j] && dist[j]<min) { min=dist[j]; k=j; } } vist[k]=true; for(j=1; j<=N; j++) //更新 { if(dist[j]>dist[k]+map[k][j]) { dist[j]=dist[k]+map[k][j]; } } } } void Traverse() { int i,j,tmp; for(i=1; i<=N; i++) { for(j=1; j<i; j++) { tmp=map[i][j]; map[i][j]=map[j][i]; map[j][i]=tmp; } } } int main() { int i,j,a,b,w,max[MAXN],result; freopen("acm.txt","r",stdin); scanf("%d%d%d",&N,&M,&X); for(i=1; i<=N; i++) { for(j=1; j<=N; j++) { map[i][j]=INF; } } memset(max,0,sizeof(max)); for(i=1; i<=M; i++) { scanf("%d%d%d",&a,&b,&w); map[a][b]=w; } Dij(); for(i=1; i<=N; i++) { max[i]=dist[i]; } Traverse(); Dij(); result=0; for(i=1; i<=N; i++) { if(result<max[i]+dist[i]) result=max[i]+dist[i]; } printf("%d\n",result); return 0; }
2.SPFA
#include <iostream> #include <fstream> using namespace std; #define MAXN 1005 #define INF 0x7fffff int map[MAXN][MAXN]; int dist[MAXN]; bool vist[MAXN]; int queue[MAXN*MAXN]; int N,X,M; void SPFA() { int i; for(i=0; i<=N; i++) { dist[i]=INF; } memset(vist,false,sizeof(vist)); dist[X]=0; //初始化节点 queue[0]=X; int head=0,tail=1; while(head<tail) { int u=queue[head]; vist[u]=true; for(i=1; i<=N; i++) //更新从u出去的边 { if(map[u][i]!=INF && dist[i]>dist[u]+map[u][i]) { dist[i]=dist[u]+map[u][i]; if(!vist[i]) { vist[i]=true; queue[tail]=i; tail++; } } } vist[u]=false; //出队 head++; } } void Traverse() { int i,j,tmp; for(i=1; i<=N; i++) { for(j=1; j<i; j++) { tmp=map[i][j]; map[i][j]=map[j][i]; map[j][i]=tmp; } } } int main() { int i,j,a,b,w,max[MAXN],result; freopen("acm.txt","r",stdin); scanf("%d%d%d",&N,&M,&X); for(i=1; i<=N; i++) { for(j=1; j<=N; j++) { map[i][j]=INF; } } memset(max,0,sizeof(max)); for(i=1; i<=M; i++) { scanf("%d%d%d",&a,&b,&w); map[a][b]=w; } SPFA(); for(i=1; i<=N; i++) { max[i]=dist[i]; } Traverse(); SPFA(); result=0; for(i=1; i<=N; i++) { if(result<max[i]+dist[i]) result=max[i]+dist[i]; } printf("%d\n",result); return 0; }
我是一名在校大学生,热爱编程,虽然起步晚了些,但我会努力的。呵呵!
数据结构 算法