zoj 2526(一道很好的最短路应用题)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1538
题意:最短路问题,但是要求出最短路的条数,同时要求出所有可能的最短路选择中javabean最多的情况。
思路:求到终点的最短路径用Dijkstra,其路径更新条件(如果到某个点有多个路径长度一样的最短路径,则选择豆子总数最多的)就是直接加个else if条件就搞定了,最后就是dfs搜一下最短路的条数了,这个我就记忆化了一下。
然后我一开始使用spfa写的,wa了好多次,orz...改成dijkstra就过了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 #define MAXN 555 8 #define inf 1<<30 9 /* 10 struct Node{ 11 int v,w; 12 }; 13 vector<Node>vet[MAXN]; 14 */ 15 int map[MAXN][MAXN]; 16 int path[MAXN]; 17 int dist[MAXN]; 18 int value[MAXN]; 19 int sum_value[MAXN]; 20 int dp[MAXN]; 21 int mark[MAXN]; 22 int n,m,st,ed; 23 24 /* 25 void SPFA(){ 26 memset(sum_value,0,sizeof(sum_value)); 27 memset(path,-1,sizeof(path)); 28 for(int i=0;i<n;i++)dist[i]=inf; 29 dist[st]=0,sum_value[st]=value[st]; 30 queue<int>Q; 31 Q.push(st); 32 while(!Q.empty()){ 33 int u=Q.front(); 34 Q.pop(); 35 for(int i=0;i<vet[u].size();i++){ 36 int v=vet[u][i].v; 37 int w=vet[u][i].w; 38 if(dist[u]+w<=dist[v]){ 39 path[v]=u; 40 Q.push(v); 41 if(dist[u]+w<dist[v]){ 42 dist[v]=dist[u]+w; 43 sum_value[v]=sum_value[u]+value[v]; 44 }else if(sum_value[v]<sum_value[u]+value[v]){ 45 sum_value[v]=sum_value[u]+value[v]; 46 } 47 } 48 } 49 } 50 } 51 */ 52 53 void Dijkstra(){ 54 memset(mark,false,sizeof(mark)); 55 memset(sum_value,0,sizeof(sum_value)); 56 memset(path,-1,sizeof(path)); 57 for(int i=0;i<n;i++)dist[i]=map[st][i]; 58 dist[st]=0,sum_value[st]=value[st],mark[st]=true; 59 int u=st; 60 for(int i=0;i<n-1;i++){ 61 int min=inf; 62 for(int j=0;j<n;j++){ 63 if(!mark[j]&&map[u][j]<inf&&dist[u]+map[u][j]<=dist[j]){ 64 if(dist[u]+map[u][j]<dist[j]){ 65 dist[j]=dist[u]+map[u][j]; 66 sum_value[j]=sum_value[u]+value[j]; 67 path[j]=u; 68 }else if(sum_value[j]<sum_value[u]+value[j]){ 69 sum_value[j]=sum_value[u]+value[j]; 70 path[j]=u; 71 } 72 } 73 } 74 for(int j=0;j<n;j++){ 75 if(!mark[j]&&min>dist[j]){ 76 min=dist[j],u=j; 77 } 78 } 79 mark[u]=true; 80 } 81 } 82 83 84 85 /* 86 int dfs(int u){ 87 if(u==ed)return 1; 88 if(dp[u])return dp[u]; 89 for(int i=0;i<vet[u].size();i++){ 90 int v=vet[u][i].v; 91 int w=vet[u][i].w; 92 if(dist[v]==dist[u]+w){ 93 dp[u]+=dfs(v); 94 } 95 } 96 return dp[u]; 97 } 98 */ 99 100 int dfs(int u){ 101 if(u==ed)return 1; 102 if(dp[u])return dp[u]; 103 for(int i=0;i<n;i++)if(u!=i){ 104 if(dist[i]==dist[u]+map[u][i]){ 105 dp[u]+=dfs(i); 106 } 107 } 108 return dp[u]; 109 } 110 111 112 void Print(int u){ 113 if(path[u]==-1){ 114 printf("%d",u); 115 return ; 116 } 117 Print(path[u]); 118 printf(" %d",u); 119 } 120 121 int main(){ 122 int u,v,w; 123 while(~scanf("%d%d%d%d",&n,&m,&st,&ed)){ 124 // for(int i=0;i<n;i++)vet[i].clear(); 125 for(int i=0;i<n;i++){ 126 map[i][i]=0; 127 for(int j=i+1;j<n;j++){ 128 map[i][j]=map[j][i]=inf; 129 } 130 } 131 for(int i=0;i<n;i++) 132 scanf("%d",&value[i]); 133 for(int i=1;i<=m;i++){ 134 scanf("%d%d%d",&u,&v,&w); 135 /* 136 Node p1,p2; 137 p1.v=v,p2.v=u; 138 p1.w=p2.w=w; 139 vet[u].push_back(p1); 140 vet[v].push_back(p2); 141 */ 142 map[u][v]=map[v][u]=w; 143 } 144 // SPFA(); 145 Dijkstra(); 146 memset(dp,0,sizeof(dp)); 147 int ans=dfs(st); 148 printf("%d %d\n",ans,sum_value[ed]); 149 Print(ed); 150 puts(""); 151 } 152 return 0; 153 }