网络流——最大流最小割
网络流黄页~~~
最大流是增广思想的杰作,针对增光特点,采用dinic阻塞流分层
调试编译通过代码
这个没什么,肯定不会考裸,模板的构建是最重要的
并且还有最小割最大流定理
(相等)
利用拆点实现割集划分即选与不选,放a或b
1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 #include<iostream> 7 #include<cmath> 8 #include<cstdlib> 9 #define maxn 10010 10 #define maxm 100010; 11 #define inf 2123450000 12 using namespace std; 13 struct edge{ 14 int from,to,cap,flow; 15 }; 16 vector <edge> edges; 17 vector <int > g[maxn]; 18 int vis[maxn],cur[maxn],d[maxn]; 19 int m=0,n,a,b,c,k,s,t; 20 void add_edge(int a,int b,int c) 21 { 22 m+=2; 23 edges.push_back({a,b,c,0}); 24 edges.push_back({b,a,0,0}); 25 g[b].push_back(m-1); 26 g[a].push_back(m-2); 27 } 28 bool bfs() 29 { 30 memset(vis,0,sizeof(vis)); 31 memset(d,0,sizeof(d)); 32 queue<int> q; 33 d[s]=0,vis[s]=1; 34 q.push(s); 35 while(!q.empty()) 36 { 37 38 int u=q.front();q.pop(); 39 for(int i=0;i<g[u].size();i++) 40 { 41 edge &e=edges[g[u][i]]; 42 if(!vis[e.to]&&e.cap>e.flow) 43 { 44 //cout<<"herebb"<<endl; 45 d[e.to]=d[u]+1; 46 vis[e.to]=1; 47 q.push(e.to); 48 } 49 } 50 } 51 return vis[t]; 52 } 53 int dfs(int x,int a) 54 { 55 if(x==t||a==0)return a; 56 int f=0,flow=0; 57 for(int &i=cur[x];i<g[x].size();i++) 58 { 59 edge &e=edges[g[x][i]]; 60 if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,(e.cap-e.flow))))) 61 { 62 a-=f; 63 flow+=f; 64 e.flow+=f; 65 edges[g[x][i]^1].flow-=f;//fanhu - 66 if(a<=0)break; 67 } 68 } 69 return flow; 70 } 71 long long maxflow(int s,int t) 72 { 73 long long flow=0; 74 while(bfs()) 75 { 76 //cout<<"here"<<endl; 77 memset(cur,0,sizeof(cur)); 78 flow+=(long long)dfs(s,2000000000); 79 } 80 return flow; 81 } 82 int main() 83 { 84 cin>>n>>k>>s>>t; 85 for(int i=1;i<=k;i++) 86 { 87 cin>>a>>b>>c; 88 add_edge(a,b,c); 89 } 90 cout<<maxflow(s,t)<<endl; 91 return 0; 92 }