网络流的几种写法

时间:2022-03-17 16:06:13

最近为了准备免修考试而在学习java和python,然后就拿了一道网络流来练练手,不过虽然是java跟python不过其实还是C++直接翻译过来的啦,所以哪些很棒的特性我一点都没有用~~ 题目:D:Til the Cows Come Home

网络流的几种写法网络流的几种写法
 1 import java.util.*;
 2 import java.lang.*;
 3 class edge{
 4     int to,nxt,cap;
 5     edge(int x,int y,int z){to = x;nxt = y;cap = z; }
 6 }
 7 public class Main{
 8     static int n,m;
 9     static edge[] edges = new edge[410];
10     static int[] nxt = new int[210],p;
11     static int[] gap = new int[210],h = new int[210];
12     static int l;
13     static void addedge(int x,int y,int z) {
14         l++;
15         edges[l*2]=new edge(y,nxt[x],z);nxt[x]=l*2;
16         edges[l*2+1]=new edge(x,nxt[y],0);nxt[y]=l*2+1;
17     }
18     static int sap(int u,int flow) {
19         if (u==n) return flow;
20         int cnt = 0;
21         for (int i=p[u];i!=0;i=edges[i].nxt){
22             if (edges[i].cap!=0&&h[u]==h[edges[i].to]+1) {
23                 int cur = sap(edges[i].to,Math.min(flow-cnt,edges[i].cap));
24                 edges[i].cap-=cur;edges[i^1].cap+=cur;
25                 p[u]=i;
26                 if ((cnt+=cur)==flow) return flow;
27             }
28         }
29         if ((--gap[h[u]])==0) h[1]=n;
30         gap[++h[u]]++;
31         p[u]=nxt[u];
32         return cnt;
33     }
34     static int maxflow(){
35         Arrays.fill(gap,0);
36         Arrays.fill(h,0);
37         p = Arrays.copyOf(nxt,210);
38         gap[0]=n;
39         int flow = 0;
40         while (h[1]<n) {
41             flow += sap(1,0x7fffffff);
42         }
43         return flow;
44     }
45     public static void main(String[] Args){
46         Scanner sc = new Scanner(System.in);
47         for (;;) {
48             try{
49                 m = sc.nextInt();n=sc.nextInt();
50                 l=0;
51                 nxt=new int[210];
52                 for (int i=0;i<m;++i) {
53                     int x=sc.nextInt(),y=sc.nextInt(),z=sc.nextInt();
54                     addedge(x,y,z);
55                 }
56                 System.out.println(maxflow());
57             }catch(Exception E){
58                 break;
59             }
60         }
61     }
62 }
View Code

在写这个程序的过程中主要还是学会了怎么写读到EOF,然后就是对java静态变量有了一点新的认识,总而言之java的语法跟c++几乎一样所以基本没有碰到什么难题。。。

这个python写的很丑别介意。。。我很多语句后面都加了分号然后不用括号的地方我都加了上去都是因为c++的锅。。。。

网络流的几种写法网络流的几种写法
 1 class edge(object) :
 2     def __init__(self,to,nxt,cap):
 3         self.to=to
 4         self.nxt=nxt
 5         self.cap=cap
 6 
 7 nxt=[0]*(300)
 8 edges = [edge(0,0,0)]*(410)
 9 l=0
10 p = []
11 gap = [0]*(300)
12 h = [0]*(300)
13     
14 def addedge(x,y,z) :
15     global l
16     l+=1
17     edges[l*2]=edge(y,nxt[x],z)
18     nxt[x]=l*2
19     edges[l*2+1]=edge(x,nxt[y],0)
20     nxt[y]=l*2+1;
21 def sap(u,flow):
22     if (u==n) :return flow
23     cnt=0
24     i = p[u];
25     while (i) :
26         if edges[i].cap and h[edges[i].to]+1==h[u] :
27             cur = sap(edges[i].to,min(flow-cnt,edges[i].cap))
28             edges[i].cap-=cur
29             edges[i^1].cap+=cur
30             p[u]=i
31             cnt+=cur;
32             if (cnt==flow): return flow;
33         i=edges[i].nxt
34     gap[h[u]]-=1;
35     if (not gap[h[u]]) :h[1]=n;
36     h[u]+=1;
37     gap[h[u]]+=1;
38     p[u]=nxt[u]
39     return cnt;
40 
41 def maxflow() :
42     global istest;
43     global p;
44     for i in nxt: p.append(i)
45     gap[0]=n;
46     flow=0
47     while (h[1]<n) :
48         flow += sap(1,0x7ffffffff)
49     return flow
50 while (1):
51     try:
52         l=0
53         nxt=[0]*(300)
54         edges = [edge(0,0,0)]*(410)
55         l=0
56         p = []
57         gap = [0]*(300)
58         h = [0]*(300)
59         m,n=map(int,input().split());
60         for i in range(m):
61             x,y,cap=map(int,input().split())
62             addedge(x,y,cap);
63         print(maxflow())
64     except:
65         break
View Code

python需要注意的就是在使用全局变量时需要声明global,然后还有就是在复制列表时不能直接a = b,这样只是吧b列表做了个引用放到a那里。

最后在附上c++的代码供大家参考(13行的sap是我最喜欢的东西了)

网络流的几种写法网络流的几种写法
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 #define maxn 410
 7 int h[maxn],gap[maxn],p[maxn],nxt[maxn];
 8 int n,m;
 9 struct edge{
10     int to,next,cap;
11 }edges[maxn];
12 int l;
13 void addedge(int x,int y,int z) {
14     l++;
15     edges[l*2]=(edge){y,nxt[x],z};nxt[x]=l*2;
16     edges[l*2+1]=(edge){x,nxt[y],0};nxt[y]=l*2+1;
17 }
18 #define inf 0x7fffffff
19 int sap(int x,int flow=inf) {
20     if (x==n) return flow;
21     int cnt=0;
22     for (int i=p[x];i;i=edges[i].next) {
23         if (edges[i].cap&&h[x]==h[edges[i].to]+1) {
24             int cur=sap(edges[i].to,min(flow-cnt,edges[i].cap));
25             edges[i].cap-=cur;edges[i^1].cap+=cur;
26             p[x]=i;
27             if ((cnt+=cur)==flow) return cnt;
28         }
29     }
30     if (!(--gap[h[x]])) h[1]=n;
31     gap[++h[x]]++;
32     p[x]=nxt[x];
33     return cnt;
34 }
35 int maxflow(){
36     memset(h,0,sizeof(h));
37     memset(gap,0,sizeof(gap));
38     for (int i=1;i<=n;++i) p[i]=nxt[i];
39     gap[0]=n;
40     int ans=0;
41     while (h[1]<n) ans+=sap(1);
42     return ans;
43 }
44 int main(){
45     while (scanf("%d%d",&m,&n)!=EOF) {
46         memset(nxt,0,sizeof(nxt));
47         l=0;
48     for (int i=1;i<=m;i++) {
49         int x,y,z;
50         scanf("%d%d%d",&x,&y,&z);
51         addedge(x,y,z);
52     }
53     printf("%d\n",maxflow());
54     }
55     return 0;
56 }
View Code