题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1385
题目意思很明确,这里就不讲了
从这道题的年份来看,n应该不会超过100,没有用floyd( 效率不高,不喜欢用),选择了dijkstra
注意两个点:一.起点和终点一样的情况,容易解决
二.字典序大小比较时,要把当前的点加进路径比较,discuss有个例子
4 0 2 3 9 2 0 1 5 3 1 0 3 9 5 3 1 0 0 0 0 1 4 ------------ output应该是 1->2->3->4这条路径吧。以前我的是 1->3->4也a了(原话,完全引用)
当前点不加进结果就会变成1->3->4,我看别人过了,以为我的也能过,WA几次了才决定改正,可能这组数据真的被加上去了
#include<iostream> #include<queue> #include<cstdlib> #include<stack>; #define MAXN 1010 #define INF 100000001 using namespace std; int n,m; typedef pair<int ,int >pii; priority_queue<pii,vector<pii>,greater<pii> >q; stack<int>que; int dis[MAXN],vis[MAXN],f[MAXN],cha[MAXN]; int map[MAXN][MAXN]; void init() { int i; for(i=0;i<=n;i++) { dis[i]=INF; vis[i]=0; f[i]=i; } } int check(int x,int y,int k) { int i; int a[110],b[110]; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); while(f[x]!=x) { que.push(x); x=f[x]; } que.push(x); i=0; while(!que.empty()) { a[i++]=que.top(); que.pop(); } a[i++]=k;//当前路径的最后一个元素 //----------------- while(f[y]!=y) { que.push(y); y=f[y]; } que.push(y); i=0; while(!que.empty()) { b[i++]=que.top(); que.pop(); } b[i++]=k;//当前路径的最后一个元素 for(i=0;i<100;i++) { if(a[i]>b[i]) return 2; else if(a[i]<b[i]) return 1; } return 0; } void dij(int x) { int i; dis[x]=0; q.push(make_pair(0,x)); while(!q.empty()) { pii tt=q.top(); q.pop(); int v=tt.second; if(vis[v]) continue; vis[v]=1; for(i=1;i<=n;i++) { if(vis[i]==0&&dis[i]>dis[v]+map[v][i]+cha[i]) { dis[i]=dis[v]+map[v][i]+cha[i]; f[i]=v; q.push(make_pair(dis[i],i)); } else if(vis[i]==0&&dis[i]==dis[v]+map[v][i]+cha[i])//相等时进行比较 { if(check(f[i],v,i)==2)//将i加进路径比较 f[i]=v; } } } } int main() { int i,j,k,x,y,a[110],yy; while(cin>>n,n) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) { cin>>map[i][j]; if(map[i][j]==-1) map[i][j]=INF; } for(i=1;i<=n;i++) cin>>cha[i]; while(cin>>x>>y,x!=-1||y!=-1) { yy=y; init(); dij(x); printf("From %d to %d :\n",x,y); memset(a,0,sizeof(a)); while(f[y]!=y) { que.push(y); y=f[y]; } que.push(y); i=0; while(!que.empty()) { a[i++]=que.top(); que.pop(); } k=i; printf("Path: "); for(i=0;i<k;i++) { if(i==0) printf("%d",a[i]); else printf("-->%d",a[i]); } printf("\n"); if(x==yy)//注意判断两个点相同的情况 printf("Total cost : %d\n\n",0); else printf("Total cost : %d\n\n",dis[yy]-cha[yy]); } } }