POJ-2135 Farm Tour 最小费用流
题目链接:http://poj.org/problem?id=2135
很容易看出来时最小费用流,但这里要注意是无向边,所以要建立两条边。为了满足退流时,花费还是最小,反向边的花费要为相反数。
1 //STATUS:G++_AC_32MS_980KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 #include<map> 13 using namespace std; 14 #define LL __int64 15 #define pii pair<int,int> 16 #define Max(a,b) ((a)>(b)?(a):(b)) 17 #define Min(a,b) ((a)<(b)?(a):(b)) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define lson l,mid,rt<<1 20 #define rson mid+1,r,rt<<1|1 21 const int MAX=1010,INF=0x3f3f3f3f; 22 const LL LLNF=0x3f3f3f3f3f3f3f3fLL; 23 24 struct Edge{ 25 int u,v,cap,w; 26 }e[MAX*40]; 27 28 int d[MAX],first[MAX],next[MAX*40],inq[MAX],p[MAX]; 29 int n,m,s,t,mt; 30 31 void adde(int a,int b,int c,int val){ 32 e[mt].u=a,e[mt].v=b,e[mt].cap=c,e[mt].w=val; 33 next[mt]=first[a],first[a]=mt++; 34 e[mt].u=b,e[mt].v=a,e[mt].cap=0,e[mt].w=-val; 35 next[mt]=first[b],first[b]=mt++; 36 } 37 38 int Mincost() 39 { 40 int i,j,x,a,cost=0; 41 queue<int> q; 42 p[s]=-1; 43 while(1){ 44 a=INF; 45 mem(d,0x3f); 46 mem(inq,0); 47 d[s]=0; 48 q.push(s); 49 while(!q.empty()){ 50 x=q.front();q.pop(); 51 inq[x]=0; 52 for(i=first[x];i!=-1;i=next[i]){ 53 if(e[i].cap && d[e[i].u]+e[i].w<d[e[i].v]){ 54 d[e[i].v]=d[e[i].u]+e[i].w; 55 p[e[i].v]=i; 56 if(!inq[e[i].v]){ 57 q.push(e[i].v); 58 inq[e[i].v]=1; 59 } 60 } 61 } 62 } 63 if(d[t]==INF)break; 64 for(i=p[t];i!=-1;i=p[e[i].u]) 65 if(e[i].cap<a)a=e[i].cap; 66 for(i=p[t];i!=-1;i=p[e[i].u]){ 67 e[i].cap-=a; 68 e[i^1].cap+=a; 69 } 70 cost+=d[t]*a; 71 } 72 return cost; 73 } 74 75 int main() 76 { 77 // freopen("in.txt","r",stdin); 78 int i,j,a,b,c; 79 while(~scanf("%d%d",&n,&m)) 80 { 81 t=n; 82 s=mt=0; 83 mem(first,-1); 84 for(i=0;i<m;i++){ 85 scanf("%d%d%d",&a,&b,&c); 86 adde(a,b,1,c); 87 adde(b,a,1,c); 88 } 89 adde(s,1,2,0); 90 91 printf("%d\n",Mincost()); 92 } 93 return 0; 94 }