老oj2146 && Pku2135 Farm Tour

Description

When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of which contains his house and the Nth of which contains the big barn. A total M (1 <= M <= 10000) paths that connect the fields in various ways. Each path connects two different fields and has a nonzero length smaller than 35,000.

To show off his farm in the best way, he walks a tour that starts at his house, potentially travels through some fields, and ends at the barn. Later, he returns (potentially through some fields) back to his house again.

He wants his tour to be as short as possible, however he doesn't want to walk on any given path more than once. Calculate the shortest tour possible. FJ is sure that some tour exists for any given farm.

//最小费用流
//问题描述:有n个点m条边组成的农场,有正边权,fj闲着没事干带游客绕农场兜一圈
//他希望这次旅行越短越好,每条边部能重复走,问题等价于在网络中找两条互不相交的s-t的路线
//用费用流求解,把双向边看成两条单向的,容量为1,费用为边权,增加两个点s,t
//s到1容量为2,n到t容量为2,然后求解即可

Input

* Line 1: Two space-separated integers: N and M.

* Lines 2..M+1: Three space-separated integers that define a path: The starting field, the end field, and the path's length.

Output

A single line containing the length of the shortest tour.

Sample Input

4 5
1 2 1
2 3 1
3 4 1
1 3 2
2 4 2

Sample Output

6

Source

最小费用流

题解:就在description里。。。。

code:

spfa费用流:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #define maxn 2005
 6 #define maxm 40050
 7 #define INF 1061109567
 8 using namespace std;
 9 char ch;
10 int n,m,a,b,c;
11 struct mincost_flow{
12     int st,en,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
13     int dist[maxn],list[maxn],pe[maxn],head,tail;
14     bool bo[maxn];
15     int flow,sum;
16     void clear(){
17         tot=1;
18         memset(now,0,sizeof(now));    
19     }
20     void put(int a,int b,int c,int d){
21         pre[++tot]=now[a];
22         now[a]=tot;
23         son[tot]=b;
24         val[tot]=c;
25         cost[tot]=d;    
26     }
27     bool spfa(){
28         memset(bo,0,sizeof(bo));
29         memset(pe,0,sizeof(pe));
30         memset(dist,63,sizeof(dist));
31         list[1]=st,bo[st]=true,dist[st]=0,head=0,tail=1;
32         while (head!=tail){
33             if (++head==maxn) head=1;
34             int u=list[head];
35             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
36                 if (dist[v]>dist[u]+cost[p]&&val[p]){
37                     dist[v]=dist[u]+cost[p],pe[v]=p;
38                     if (!bo[v]){
39                         if (++tail==maxn) tail=1;
40                         list[tail]=v,bo[v]=true;    
41                     }
42                 }
43             bo[u]=false;
44         }
45         if (dist[en]==INF) return false;
46         int tmp=INF,t=0;
47         for (int u=en,p=pe[u];u!=st;u=son[p^1],p=pe[u]) tmp=min(tmp,val[p]);
48         for (int u=en,p=pe[u];u!=st;u=son[p^1],p=pe[u]) val[p]-=tmp,val[p^1]+=tmp,t+=cost[p];
49         flow+=tmp,sum+=t*tmp;
50         return true;
51     }
52     void calc(){
53         flow=sum=0;
54         for (;spfa(););    
55     }
56 }T;
57 void read(int &x){
58     for (ch=getchar();!isdigit(ch);ch=getchar());
59     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
60 }
61 int main(){
62     read(n),read(m);
63     T.clear(),T.st=0,T.en=n+1,T.put(0,1,2,0),T.put(1,0,0,0),T.put(n,n+1,2,0),T.put(n+1,n,0,0);
64     for (int i=1;i<=m;i++) read(a),read(b),read(c),T.put(a,b,1,c),T.put(b,a,0,-c),T.put(b,a,1,c),T.put(a,b,0,-c);
65     T.calc();
66     printf("%d
",T.sum);
67     return 0;    
68 }

 zkw费用流:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define maxn 1005
 7 #define maxm 40010
 8 #define inf 1061109567
 9 using namespace std;
10 char ch;
11 bool ok;
12 void read(int &x){
13     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
14     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
15     if (ok) x=-x;
16 }
17 int n,m,a,b,d;
18 struct zkw_costflow{
19     int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
20     int dis[maxn],totflow,totcost,tmp,sla[maxn];
21     bool bo[maxn];
22     void init(){s=0,t=n+1,tot=1,memset(now,0,sizeof(now));}
23     void put(int a,int b,int c,int d){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c,cost[tot]=d;}
24     void add(int a,int b,int c,int d){put(a,b,c,d),put(b,a,0,-d);}
25     int dfs(int u,int rest,int totval){
26         if (u==t){totcost+=rest*totval;return rest;}
27         int ans=0; bo[u]=1;
28         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
29             if (val[p]&&!bo[v]){
30                 int d=cost[p]+dis[u]-dis[v];
31                 if (!d){
32                     int d=dfs(v,min(rest,val[p]),totval+cost[p]);
33                     val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
34                 }
35                 else sla[v]=min(sla[v],d);
36             }
37         return ans;
38     }
39     bool relax(){
40         int d=inf;
41         for (int u=s;u<=t;u++) if (!bo[u]) d=min(d,sla[u]);
42         if (d==inf) return false;
43         for (int u=s;u<=t;u++) if (!bo[u]) dis[u]+=d;
44         return true;
45     }
46     void work(){
47         memset(dis,0,sizeof(dis)),totflow=totcost=0;
48         do{
49             memset(sla,63,sizeof(sla));
50             do{
51                 memset(bo,0,sizeof(bo));
52                 tmp=dfs(s,inf,0),totflow+=tmp;
53             }while (tmp);
54         }while (relax());
55     }
56 }f;
57 int main(){
58     read(n),read(m),f.init(),f.add(f.s,1,2,0),f.add(n,f.t,2,0);
59     for (int i=1;i<=m;i++) read(a),read(b),read(d),f.add(a,b,1,d),f.add(b,a,1,d);
60     f.work();
61     printf("%d
",f.totcost);
62     return 0;
63 }

消负圈费用流:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define maxn 1005
 7 #define maxm 40010
 8 #define inf 1061109567
 9 using namespace std;
10 char ch;
11 bool ok;
12 void read(int &x){
13     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
14     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
15     if (ok) x=-x;
16 }
17 int n,m,a,b,d;
18 struct costflow{
19     int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
20     int dis[maxn],head,tail,list[maxn];
21     int top,stack[maxn],idx,path[maxn];
22     bool in[maxn],bo[maxn];
23     int totflow,totcost;
24     void init(){s=0,t=n+1,tot=1,memset(now,0,sizeof(now));}
25     void put(int a,int b,int c,int d){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c,cost[tot]=d;}
26     void add(int a,int b,int c,int d){put(a,b,c,d),put(b,a,0,-d);}
27     bool bfs(){
28         memset(bo,0,sizeof(bo));
29         head=0,tail=1,list[1]=s,dis[s]=0,bo[s]=1;
30         while (head<tail){
31             int u=list[++head];
32             for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
33                 if (val[p]&&!bo[v]) bo[v]=1,dis[v]=dis[u]+1,list[++tail]=v;
34         }
35         return bo[t];
36     }
37     int dfs(int u,int rest,int totval){
38         if (u==t){totcost+=rest*totval;return rest;}
39         int ans=0;
40         for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
41             if (val[p]&&dis[v]==dis[u]+1){
42                 int d=dfs(v,min(rest,val[p]),totval+cost[p]);
43                 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d;
44             }
45         if (!ans) dis[u]=-1;
46         return ans;
47     }
48     void dinic(){
49         totflow=totcost=0;
50         while (bfs()) totflow+=dfs(s,inf,0);
51     }
52     int spfa(int u){
53         in[u]=1;
54         for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
55             if (val[p]&&dis[v]>dis[u]+cost[p]){
56                 dis[v]=dis[u]+cost[p],path[v]=p;
57                 if (in[v]) return v;
58                 int t=spfa(v); if (t!=-1) return t;
59             }
60         in[u]=0; return -1;
61     }
62     int find(){
63         memset(in,0,sizeof(in));
64         memset(dis,0,sizeof(dis));
65         memset(path,-1,sizeof(path));
66         for (int i=s;i<=t;i++){
67             int u=spfa(i);
68             if (u!=-1) return u;
69         }
70         return -1;
71     }        
72     void relax(int t){
73         int flow=inf,sum=0,u;
74         for (u=t;son[path[u]^1]!=t;u=son[path[u]^1]) flow=min(flow,val[path[u]]),sum+=cost[path[u]];
75         flow=min(flow,val[path[u]]),sum+=cost[path[u]];
76         for (u=t;son[path[u]^1]!=t;u=son[path[u]^1]) val[path[u]]-=flow,val[path[u]^1]+=flow;
77         val[path[u]]-=flow,val[path[u]^1]+=flow,totcost+=flow*sum;
78     }
79     void work(){
80         dinic();
81         for (int t=find();t!=-1;t=find()) relax(t);
82     }
83 }f;
84 int main(){
85     read(n),read(m),f.init(),f.add(f.s,1,2,0),f.add(n,f.t,2,0);
86     for (int i=1;i<=m;i++) read(a),read(b),read(d),f.add(a,b,1,d),f.add(b,a,1,d);
87     f.work();
88     printf("%d
",f.totcost);
89     return 0;
90 }
原文地址:https://www.cnblogs.com/chenyushuo/p/5141104.html