HDU 2135 最小费用流

http://poj.org/problem?id=2135

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #define nMAX 1002
  6 #define mMAX 10005
  7 #define inf 99999999
  8 using namespace std;
  9 int head[nMAX],qu[nMAX],dis[nMAX],pre[nMAX];
 10 bool vs[nMAX];
 11 int n,s_edge,ans;
 12 struct Edge
 13 {
 14     int v,co,cap,nxt;
 15 }edge[4*mMAX];
 16 void addedge(int u,int v,int cap,int co)
 17 {
 18     s_edge++;
 19     edge[s_edge].v=v;
 20     edge[s_edge].cap=cap;
 21     edge[s_edge].co=co;
 22     edge[s_edge].nxt=head[u];
 23     head[u]=s_edge;
 24 
 25     s_edge++;
 26     edge[s_edge].v=u;
 27     edge[s_edge].cap=0;
 28     edge[s_edge].co=-co;
 29     edge[s_edge].nxt=head[v];
 30     head[v]=s_edge;
 31 }
 32 void spfa(int u)
 33 {
 34     int i,j,start,tail;
 35     for(i=1;i<=n;i++)
 36     {
 37         dis[i]=inf;
 38         vs[i]=0;
 39     }
 40     dis[u]=0;
 41     vs[u]=1;
 42     start=0, tail=1;
 43     qu[start]=u;
 44     while(start!=tail)
 45     {
 46         int t=qu[start++];
 47         for(int e=head[t];e;e=edge[e].nxt)
 48         {
 49             int v=edge[e].v;
 50             if(edge[e].cap&&dis[v]>dis[t]+edge[e].co)
 51             {
 52                 dis[v]=dis[t]+edge[e].co;
 53                 pre[v]=e;
 54                 if(!vs[v])
 55                 {
 56                     vs[v]=1;
 57                     qu[tail++]=v;
 58                     if(tail==nMAX)tail=0;
 59                 }
 60             }
 61         }
 62         vs[t]=0;
 63         if(start==nMAX)start=0;
 64     }
 65     //if(dis[n]==inf)return 0;
 66     //return 1;
 67 }
 68 void end(int s,int t)
 69 {
 70     int p,u;
 71     for(u=t;u!=s;u=edge[p^1].v)
 72     {
 73         p=pre[u];
 74         edge[p].cap-=1;
 75         edge[p^1].cap+=1;
 76         ans+=edge[p].co;
 77     }
 78 }
 79 int main()
 80 {
 81     int i,j,k,M;
 82     while(~scanf("%d%d",&n,&M))
 83     {
 84         memset(head,0,sizeof(head));
 85         s_edge=1;
 86         while(M--)
 87         {
 88             scanf("%d%d%d",&i,&j,&k);
 89             addedge(i,j,1,k);
 90             addedge(j,i,1,k);
 91         }
 92         ans=0;
 93         for(i=1;i<=2;i++)
 94         {
 95             spfa(1);
 96             end(1,n);
 97         }
 98         printf("%d\n",ans);
 99     }
100     return 0;
101 }

 

题意:有N个点,从1~N,由两条路从1走到N,要求路径不重复,求两趟所走的最少距离是多少

开始考虑求两次最短路,这个方法不靠谱,因为求完一条最短路把边删掉后,有可能从1到N不在连通

应为最小费流,两点之间的权为费用,容量为1。可以控制股从1到N走两次,也可以建一个超级原点,到1的费用为0,流量为2

代码:

posted @ 2012-08-07 12:42  快乐.  阅读(149)  评论(0编辑  收藏  举报