poj 2135 Farm Tour【 最小费用最大流 】

第一道费用流的题目---

其实---还是不是很懂,只知道沿着最短路找增广路

建图

源点到1连一条容量为2(因为要来回),费用为0的边

n到汇点连一条容量为2,费用为0的边

另外的就是题目中输入的了

另外这题是无向边-----

maxn 开到1000会re----

存个模板先吧------------------------------------------

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<set>
  7 #include<map>
  8 #include<stack>
  9 #include<vector>
 10 #include<queue>
 11 #include<string>
 12 using namespace std;
 13 
 14 typedef long long LL;
 15 const int maxn = 5000;
 16 const int INF = (1 << 30) - 1;
 17  
 18 int first[maxn],vis[maxn],dis[maxn],pos[maxn],ecnt,size;
 19 
 20 struct Edge{
 21     int v,next,cap,cost;
 22 } e[10*maxn];
 23 
 24 void init(){
 25     ecnt = 0;
 26     memset(first,-1,sizeof(first));
 27 }
 28   
 29 void add_edge(int u,int v,int cap,int cost){
 30     e[ecnt].v = v;
 31     e[ecnt].cap = cap;
 32     e[ecnt].cost = cost;
 33     e[ecnt].next = first[u];
 34     first[u] = ecnt++;
 35     
 36     e[ecnt].v = u;
 37     e[ecnt].cap = 0;
 38     e[ecnt].cost = -cost;
 39     e[ecnt].next = first[v];
 40     first[v] = ecnt++;
 41 }
 42   
 43 bool SPFA(int s, int t)
 44 {
 45     int u,v,i;
 46     queue <int> q;
 47     memset(vis,0,sizeof(vis));
 48     for(i= 0;i <= size;i++) dis[i]=INF;
 49     
 50     dis[s]=0;
 51     vis[s]=1;
 52     q.push(s);
 53     
 54     while(!q.empty()){
 55         u=q.front(); q.pop(); vis[u]=0;
 56         for (i = first[u]; ~i;i = e[i].next){
 57                v=e[i].v; 
 58                if(e[i].cap > 0&& dis[u]+e[i].cost < dis[v]){
 59                   dis[v]=dis[u]+e[i].cost;
 60                   pos[v]=i;
 61                   if(!vis[v]){
 62                      vis[v]=1;
 63                      q.push(v);
 64                   }
 65                }
 66           }
 67     }
 68     return dis[t] != INF;
 69 }
 70 
 71 LL MCMF(int s,int t)
 72 {
 73     int i;
 74     LL cost=0,flow=0;
 75     while(SPFA(s,t)){
 76         int d=INF;
 77         for (i = t;i != s;i = e[pos[i]^1].v){
 78             d = min(d,e[pos[i]].cap);
 79         }
 80         for(i = t;i != s;i = e[pos[i]^1].v){
 81             e[pos[i]].cap -= d;
 82             e[pos[i]^1].cap += d;
 83         }
 84         flow += d;
 85         cost += dis[t]*d;
 86     }
 87     return cost;
 88 }
 89 
 90 
 91 int main(){
 92     int n,m;
 93     while(scanf("%d %d",&n,&m) != EOF){
 94         init();
 95         size = n+1;
 96         add_edge(0,1,2,0); add_edge(1,0,2,0);
 97         add_edge(n+1,n,2,0);add_edge(n,n+1,2,0);
 98         
 99         for(int i = 0;i < m;i++){
100             int u,v,w;
101             scanf("%d %d %d",&u,&v,&w);
102             add_edge(u,v,1,w);
103             add_edge(v,u,1,w);
104         }
105         printf("%I64d
",MCMF(0,n+1));
106     }
107     return 0;
108 }
View Code
原文地址:https://www.cnblogs.com/wuyuewoniu/p/4730970.html