Two shortest

sgu185:http://acm.sgu.ru/problem.php?contest=0&problem=185

题意:找两条最短路径,没有边相交的最短路劲,并且输出路径。

题解:这一题和zoj2760,这两题的基本差不多,但是却用了不同的方法,而且输出dfs也不理解。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdio>
  5 #include<queue>
  6 #define INF 1000000000
  7 using namespace std;
  8 const int N=405;
  9 const int M=160008;
 10 int dist[N],mp[N][N];
 11 struct Node{
 12    int v;
 13    int f;
 14    int next;
 15 }edge[M];
 16 int n,m,u,v,w,cnt,sx,ex;
 17 int head[N],pre[N];
 18 bool visit[N];
 19 void init(){
 20     cnt=0;
 21     memset(head,-1,sizeof(head));
 22 }
 23 void add(int u,int v,int w){
 24     edge[cnt].v=v;
 25     edge[cnt].f=w;
 26     edge[cnt].next=head[u];
 27     head[u]=cnt++;
 28     edge[cnt].f=0;
 29     edge[cnt].v=u;
 30     edge[cnt].next=head[v];
 31     head[v]=cnt++;
 32 }
 33 bool BFS(){
 34   memset(pre,0,sizeof(pre));
 35   pre[sx]=1;
 36   queue<int>Q;
 37   Q.push(sx);
 38  while(!Q.empty()){
 39      int d=Q.front();
 40      Q.pop();
 41      for(int i=head[d];i!=-1;i=edge[i].next    ){
 42         if(edge[i].f&&!pre[edge[i].v]){
 43             pre[edge[i].v]=pre[d]+1;
 44             Q.push(edge[i].v);
 45         }
 46      }
 47   }
 48  return pre[ex]>0;
 49 }
 50 int dinic(int flow,int ps){
 51     int f=flow;
 52      if(ps==ex)return f;
 53      for(int i=head[ps];i!=-1;i=edge[i].next){
 54         if(edge[i].f&&pre[edge[i].v]==pre[ps]+1){
 55             int a=edge[i].f;
 56             int t=dinic(min(a,flow),edge[i].v);
 57               edge[i].f-=t;
 58               edge[i^1].f+=t;
 59              flow-=t;
 60              if(flow<=0)break;
 61         }
 62 
 63      }
 64       if(f-flow<=0)pre[ps]=-1;
 65       return f-flow;
 66 }
 67 void spfa(){
 68    for(int i=1;i<=n;i++){
 69       dist[i]=INF;
 70       visit[i]=0;
 71    }
 72    queue<int>Q;
 73    dist[1]=0;
 74    visit[1]=1;
 75    Q.push(1);
 76    while(!Q.empty()){
 77       int u=Q.front();
 78       Q.pop();
 79       visit[u]=0;
 80       for(int i=1;i<=n;i++){
 81           if(mp[u][i]<INF){
 82              if(dist[u]+mp[u][i]<dist[i]){
 83                 dist[i]=dist[u]+mp[u][i];
 84                 if(!visit[i]){
 85                     visit[i]=1;
 86                     Q.push(i);
 87                 }
 88              }
 89           }
 90       }
 91    }
 92    for(int i=1;i<=n;i++)
 93    for(int j=1;j<=n;j++){
 94       if(dist[i]+mp[i][j]==dist[j]&&mp[i][j]!=INF)
 95         add(i,j,1);
 96    }
 97 }
 98 int solve(){
 99     int sum=0;
100     while(BFS()){
101        sum+=dinic(INF,sx);
102     }
103 
104     return sum;
105 }
106 void dfs(int u,int fa){
107     if(u == n){printf("%d\n",u);return ;}
108     else printf("%d ",u);
109     for(int i = head[u]; i!=-1; i = edge[i].next){
110         if(edge[i^1].f!= 1 ||(i&1))continue;
111         int v = edge[i].v;
112         if(v == fa)continue;
113         edge[i^1].f = 0;
114         dfs(v, u);
115         return;
116     }
117 }
118 int main(){
119     while(~scanf("%d%d",&n,&m)) {
120          init();
121          for(int i=1;i<=n;i++){
122             for(int j=1;j<=n;j++)
123             mp[i][j]=INF;
124            // mp[i][i]=0;
125          }
126 
127          for(int i=1;i<=m;i++){
128             scanf("%d%d%d",&u,&v,&w);
129             if(mp[u][v]>w)
130            mp[u][v]=mp[v][u]=w;
131          }
132          spfa(); sx=1,ex=n;
133         if(solve()<2||dist[n]==INF)printf("No solution\n");
134         else{
135             dfs(1,1);
136             dfs(1,1);
137         }
138     }
139     return 0;
140 }
View Code

 

posted on 2014-09-01 18:07  天依蓝  阅读(166)  评论(0编辑  收藏  举报

导航