网络流--Dinic(自用,勿看)

注意:这是一篇个人学习笔记,如果有人因为某些原因点了进来并且要看一下,请一定谨慎地阅读,因为可能存在各种奇怪的错误,如果有人发现错误请指出谢谢!


https://www.luogu.org/problemnew/show/P3376

来自蓝书:

时间复杂度O(n^2*m)

所有容量均为1,可以证明时间复杂度O(min(n^(2/3),m^(1/2))*m)

除了源点和汇点之外,每个点要么只有一条入弧,且容量为1,要么只有一条出弧,且容量为1,其他弧的容量为任意整数,可以证明时间复杂度O(n^(1/2)*m)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 #include<queue>
 6 using namespace std;
 7 #define fi first
 8 #define se second
 9 #define mp make_pair
10 #define pb push_back
11 typedef long long ll;
12 typedef unsigned long long ull;
13 typedef pair<int,int> pii;
14 namespace F
15 {
16 
17 struct E
18 {
19     int to,nxt,from,cap,flow;
20 }e[200100];
21 int f1[10100],ne=1;
22 int S,T,n;
23 int d[10100];
24 void clr(int n)
25 {
26     ne = 1;
27     memset(f1, 0, sizeof(f1[0]) * (n+5));
28 }
29 bool bfs()
30 {
31     int k,u;
32     memset(d,0,sizeof(int)*(n+1));
33     queue<int> q;
34     q.push(S);d[S]=1;
35     while(!q.empty())
36     {
37         u=q.front();q.pop();
38         for(k=f1[u];k;k=e[k].nxt)
39             if(!d[e[k].to]&&e[k].cap>e[k].flow)
40             {
41                 d[e[k].to]=d[u]+1;
42                 //if(e[k].to==T)    return 1;
43                 q.push(e[k].to);
44             }
45     }
46     //return 0;
47     return d[T];
48 }
49 int cur[10100];
50 int dfs(int u,int x)
51 {
52     if(u==T||x==0)    return x;
53     int flow=0,f;
54     for(int &k=cur[u];k;k=e[k].nxt)
55         if(e[k].cap>e[k].flow&&d[e[k].to]==d[u]+1)
56         {
57             f=dfs(e[k].to,min(x-flow,e[k].cap-e[k].flow));
58             e[k].flow+=f;e[k^1].flow-=f;flow+=f;
59             if(flow==x)    return flow;
60         }
61     return flow;
62 }
63 int solve()
64 {
65     int flow=0;
66     while(bfs())
67     {
68         memcpy(cur,f1,sizeof(int)*(n+1));
69         flow+=dfs(S,0x3f3f3f3f);
70     }
71     return flow;
72 }
73 void me(int a,int b,int c)
74 {
75     e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
76     e[ne].from=a;e[ne].cap=c;e[ne].flow=0;
77     e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
78     e[ne].from=b;e[ne].cap=0;e[ne].flow=0;
79 }
80 
81 }
82 int n,m;
83 int main()
84 {
85     int i,a,b,c;
86     scanf("%d%d%d%d",&n,&m,&F::S,&F::T);F::n=n;
87     for(i=1;i<=m;i++)
88     {
89         scanf("%d%d%d",&a,&b,&c);
90         F::me(a,b,c);
91     }
92     printf("%d",F::solve());
93     return 0;
94 }
View Code

upd2022.08.19  出于多组数据的需要做出了相应修改

(补上37行,42行改成41行,跑的要更快,但是感觉不太对所以没有写)

 

posted @ 2018-09-09 21:46  hehe_54321  阅读(158)  评论(0编辑  收藏  举报
AmazingCounters.com