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 }
View Code

 

你可能感兴趣的:(最短路)