1 /********************************************************
  2 题目:    Farm Tour(poj 2135)
  3 链接:    http://poj.org/problem?id=2135
  4 算法:    最小费用最大流
  5 题意:    在无向图中,从1走n,在从n走到1的最小路
  6           不能走重复的路;
  7 算法思想:每次从最小路增广。
  8 ********************************************************/
  9 #include<cstdio>
 10 #include<cstring>
 11 #include<iostream>
 12 #include<algorithm>
 13 #include<queue>
 14 #include<vector>
 15 using namespace std;
 16 
 17 
 18 const int mx=10005;
 19 const int inf=1000000000;
 20 struct Eage
 21 {
 22     int u,v,next;
 23     int cap,cost;
 24 };
 25 Eage eage[mx*4];
 26 int head[mx],d[mx];
 27 int father[mx];
 28 bool vs[mx];
 29 int pos,n,m;
 30 
 31 void add(int u,int v,int cap,int cost)
 32 {
 33     eage[pos].u=u;
 34     eage[pos].v=v;
 35     eage[pos].cap=cap;
 36     eage[pos].cost=cost;
 37     eage[pos].next=head[u];
 38     head[u]=pos++;
 39 }
 40 
 41 bool spfa()
 42 {
 43      fill(vs,vs+n+2,false);
 44      fill(d,d+n+2,inf);
 45      fill(father,father+n+2,-1);
 46      queue<int>q;
 47      d[0]=0;
 48      q.push(0);
 49      while (!q.empty())
 50      {
 51          int u=q.front();
 52          q.pop();
 53          vs[u]=false;
 54          for (int i=head[u];i!=-1;i=eage[i].next)
 55          {
 56              int v=eage[i].v;
 57              if (eage[i].cap&&d[v]>d[u]+eage[i].cost)
 58              {
 59                  d[v]=d[u]+eage[i].cost;
 60                  father[v]=i;
 61                  if (!vs[v])
 62                  {
 63                      vs[v]=true;
 64                      q.push(v);
 65                  }
 66              }
 67          }
 68      }
 69      if (father[n+1]==-1) return false;
 70      return true;
 71 }
 72 
 73 int solve()
 74 {
 75     int ans=0;
 76     while (spfa())
 77     {
 78         ans+=d[n+1];
 79         int u=n+1;
 80         while (u!=0)
 81         {
 82             int i=father[u];
 83             eage[i].cap--;
 84             eage[i^1].cap++;
 85             u=eage[i].u;
 86         }
 87     }
 88     return ans;
 89 }
 90 
 91 int main()
 92 {
 93     scanf("%d%d",&n,&m);
 94     pos=0;
 95     fill(head,head+n+2,-1);
 96     while (m--)
 97     {
 98         int u,v,w;
 99         scanf("%d%d%d",&u,&v,&w);
100         add(u,v,1,w);
101         add(v,u,0,-w);
102         add(v,u,1,w);
103         add(u,v,0,-w);
104     }
105     add(0,1,2,0);
106     add(2,0,0,0);
107     add(n,n+1,2,0);
108     add(n+1,n,0,0);
109     printf("%d\n",solve());
110     return 0;
111 }

 

posted on 2016-07-15 10:25  pb2016  阅读(223)  评论(0编辑  收藏  举报