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 }