HDU1385 Minimum Transport Cost(最短路输出字典序路径floyd/逆序spfa)
题意:先给你一张你n * n的图,代表城市间的距离,然后,给出n个tax的费用,然后很多询问,问你a到b的最少费用,并且打印路径(字典序)
注意tax的费用起点和终点不算
floyd求字典序路径:
/* *********************************************** Author :devil Created Time :2016/6/2 11:35:15 ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=105; int n,mp[N][N],tax[N],path[N][N]; void floyd() { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) path[i][j]=j; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int tmp=mp[i][k]+mp[k][j]+tax[k]; if(tmp<mp[i][j]) { mp[i][j]=tmp; path[i][j]=path[i][k]; } else if(tmp==mp[i][j]) path[i][j]=min(path[i][j],path[i][k]); } } int main() { //freopen("in.txt","r",stdin); int st,ed; while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%d",&mp[i][j]); if(mp[i][j]==-1) mp[i][j]=0x3f3f3f3f; } for(int i=1;i<=n;i++) scanf("%d",&tax[i]); floyd(); while(scanf("%d%d",&st,&ed)==2&&(st+ed)!=-2) { printf("""From %d to %d :\n",st,ed); printf("Path: %d",st); int tmp=st; while(tmp!=ed) { printf("-->%d",path[tmp][ed]); tmp=path[tmp][ed]; } printf("\nTotal cost : %d\n\n",mp[st][ed]); } } return 0; }
逆序spfa:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <cmath> #include <vector> #include <algorithm> using namespace std; #define maxn 1005 #define inf 1e8 int a[maxn][maxn],tax[maxn],dis[maxn],fa[maxn],ans[maxn],n,x,y,temp; bool vis[maxn]; void spfa() { memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) { dis[i]=fa[i]=inf; vis[i]=false; } dis[y]=0; queue<int>q; q.push(y); vis[y]=true; while(!q.empty()) { temp=q.front(); q.pop(); for(int i=1;i<=n;i++) { if(-1==a[i][temp]||i==temp) continue; else { if(dis[temp]+tax[i]+a[i][temp]<dis[i]) { dis[i]=dis[temp]+tax[i]+a[i][temp]; fa[i]=temp; if(vis[i]==false) { q.push(i); vis[i]=true; } } else if(dis[temp]+tax[i]+a[i][temp]==dis[i]&&temp<fa[i]) fa[i]=temp; } } vis[temp]=false; } ans[0]=x; temp=0; while(fa[ans[temp]]!=inf) { ans[temp+1]=fa[ans[temp]]; temp++; } printf("From %d to %d :\nPath: ",x,y); for(int i=0;i<temp;i++) printf("%d-->",ans[i]); printf("%d\n",ans[temp]); printf("Total cost : %d\n\n",dis[x]-tax[x]); } int main() { while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) scanf("%d",&tax[i]); while(~scanf("%d%d",&x,&y)&&x!=-1) { if(x!=y) spfa(); else { printf("From %d to %d :\n",x,y); printf("Path: %d\n",x); printf("Total cost : 0\n\n"); } } } return 0; }