hdu 1385 spfa和floyd,dijkstra记录最短最小字典序的路径
2015-05-06 10:58
627 查看
/* spfa记录字典序最小的路径 */ #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define inf 0x3fffffff #define N 1100 int a ; int b ; int n; int pre ,dis ,vis ; void init() { memset(pre,-1,sizeof(pre)); memset(vis,0,sizeof(vis)); } int Min(int v,int vv) { return v>vv?vv:v; } int len; void dfs(int k,char s[]) { if(k==-1)return ; dfs(pre[k],s); s[len++]=k+'0'; return ; } int cmp(int jnext,int now) { char sf ,sn ; len=0; dfs(jnext,sf); sf[len]=0; len=0; dfs(now,sn); sn[len++]=jnext+'0'; sn[len]=0; if(strcmp(sf,sn)>0) return 1; return 0; } void spfa(int s,int t) { int i; for(i=1; i<=n; i++) dis[i]=inf; dis[s]=0; queue<int>q; q.push(s); while(!q.empty()) { int cur=q.front(); q.pop(); vis[cur]=0; for(i=1; i<=n; i++) { if(dis[cur]==inf)continue; if(a[cur][i]<0||i==cur)continue; if(dis[i]>dis[cur]+a[cur][i]+b[i]) { dis[i]=dis[cur]+a[cur][i]+b[i]; pre[i]=cur; if(!vis[i]) { vis[i]=1; q.push(i); } } else if(dis[i]==dis[cur]+a[cur][i]+b[i]&&cmp(i,cur))//同时要比较如果选cur那么字典序会不会变小 pre[i]=cur; } } return ; } void print(int t) { if(pre[t]==-1) { printf("%d",t); return ; } print(pre[t]); printf("-->%d",t); return ; } int main() { int i,s,j,t; while(scanf("%d",&n),n) { for(i=1; i<=n; i++) for(j=1; j<=n; j++) scanf("%d",&a[i][j]); for(i=1; i<=n; i++) scanf("%d",&b[i]); while(scanf("%d%d",&s,&t),s!=-1&&t!=-1) { int sb=b[s],st=b[t];//这里我认为不需要每次置0 b[s]=0;//,在下面输出dis[t]-b[t]就可以了,但是wa b[t]=0;// init(); spfa(s,t); printf("From %d to %d :\n",s,t); printf("Path: "); print(t); printf("\n"); printf("Total cost : %d\n\n",dis[t]); b[s]=sb;// b[t]=st;// } } return 0; }
/* floyd记录最短字典序最小的路径 */ #include<stdio.h> #include<string.h> #define N 550 #define inf 0x3fffffff int dis ,path ; int b ; int n; void floyd() { int i,j,k; for(k=1; k<=n; k++) for(i=1; i<=n; i++) for(j=1; j<=n; j++) { if(dis[i][k]==inf||dis[k][j]==inf)continue; int tmp=dis[i][k]+dis[k][j]+b[k]; if(dis[i][j]>tmp) { dis[i][j]=tmp; path[i][j]=path[i][k]; } else if(dis[i][j]==tmp&&path[i][j]>path[i][k]) //同时判断字典序是否最小 path[i][j]=path[i][k]; } return ; } int main() { int i,j,k; while(scanf("%d",&n),n) { for(i=1; i<=n; i++) for(j=1; j<=n; j++) { scanf("%d",&dis[i][j]); if(dis[i][j]==-1)dis[i][j]=inf; path[i][j]=j; } for(i=1; i<=n; i++) scanf("%d",&b[i]); floyd(); int s,t; while(scanf("%d%d",&s,&t),s!=-1&&t!=-1) { printf("From %d to %d :\n",s,t); printf("Path: "); printf("%d",s); k=s; while(k!=t) { k=path[k][t]; printf("-->%d",k); } printf("\n"); printf("Total cost : %d\n\n",dis[s][t]); } } return 0; }
/* dijkstar算法求最短最小字典序路径 */ #include<stdio.h> #include<string.h> #define N 550 #define inf 0x3fffffff int pre ,dis ,vis ; int a ; int b ; int n; void init() { memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); } int len; void dfs(int k,char s[]) { if(k==-1) return ; dfs(pre[k],s); s[len++]=k+'0'; } int cmp(int fir,int now) { char sf ,sn ; len=0; dfs(fir,sf); sf[len]=0; len=0; dfs(now,sn); sn[len++]=fir+'0'; sn[len]=0; if(strcmp(sf,sn)>0) return 1; return 0; } void dijkstra(int s) { int i,j; for(i=1; i<=n; i++) { if(i==s)continue;// dis[i]=a[s][i]+b[i];//初始化注意 if(a[s][i]<inf) pre[i]=s; } dis[s]=0; vis[s]=1; for(i=1; i<=n; i++) { int index,minn=inf; for(j=1; j<=n; j++) if(minn>dis[j]&&vis[j]==0) { minn=dis[j]; index=j; } vis[index]=1; for(j=1; j<=n; j++) if(vis[j]==0&&a[index][j]<inf) { if(dis[j]>dis[index]+a[index][j]+b[j]) { dis[j]=dis[index]+a[index][j]+b[j]; pre[j]=index; } else if(dis[j]==dis[index]+a[index][j]+b[j]&&cmp(j,index))//和spfa一样判断最小字典序 pre[j]=index; } } return ; } void print(int k) { if(pre[k]==-1) { printf("%d",k); return ; } print(pre[k]); printf("-->%d",k); } int main() { int i,j; while(scanf("%d",&n),n) { for(i=1; i<=n; i++) for(j=1; j<=n; j++) { scanf("%d",&a[i][j]); if(a[i][j]==-1) a[i][j]=inf; } for(i=1; i<=n; i++) scanf("%d",&b[i]); int s,t; while(scanf("%d%d",&s,&t),s!=-1&&t!=-1) { int sf=b[s],st=b[t]; b[s]=0; b[t]=0; init(); dijkstra(s); printf("From %d to %d :\n",s,t); printf("Path: "); print(t); printf("\n"); printf("Total cost : %d\n\n",dis[t]); b[s]=sf;// b[t]=st;// } } return 0; }
相关文章推荐
- HDU 1385 Minimum Transport Cost (Floyd求最短路径+记录字典序路径)
- hdu 1385 Minimum Transport Cost (最小字典序最短路径)
- 最短路径算法 dijkstra + floyd + spfa 【记录 总结】
- 最短路径:Dijkstra,Bellman,SPFA,Floyd该算法的实施
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- hdu-1385 Minimum Transport Cost(Dijkstra最短路径算法)
- 杭电1874-畅通工程续(最短路径,dijkstra,spfa,floyd)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- 几大最短路径算法比较(Floyd & Dijkstra & Bellman-Ford & SPFA)
- hdoj 1385 Minimum Transport Cost(floyd 记录最短路径)
- hdu 1385 最短路径按字典数输出
- 最短路径算法 模板_Dijkstra_Bellman.ford_Floyd_spfa
- 几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较
- hdu 1385 Minimum Transport Cost(floyd && 记录路径)
- hdu 1358 floyd+输出字典需最小最短路径
- POJ 1847 Tram (简单最短路径dijkstra-floyd-spfa)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- hdoj-1874 畅通工程续【最短路径--dijkstra&&floyd&&spfa】
- HDU 2544:最短路( 最短路径入门 &&Dijkstra && floyd )