学习:
http://blog.csdn.net/y990041769/article/details/21026445
网络流所有算法比较:
http://www.cnblogs.com/longdouhzt/archive/2012/05/20/2510743.html
hdu 1532
求最大流
#include <iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#define M 1000
#define INF 2147483647
using namespace std;
struct Edge{
int from,to,cap,flow;
Edge(int u,int v,int c,int f) :from(u),to(v),cap(c),flow(f) {}
};
struct EdmondsKarp{
int n,m;
vector<Edge> edges;
vector<int> G[M*2+5];
int a[M+5],p[M+5];
void init(int n)
{
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0)); //当是无向图时,反向边容量也是cap,有向边时,反向边容量是0</span>
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
int Maxflow(int s,int t){
int flow=0;
for(;;){
memset(a,0,sizeof(a));
queue<int> Q;
Q.push(s);
a[s]=INF;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=0;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(!a[e.to] && e.cap>e.flow){
p[e.to]=G[x][i];
a[e.to]=min(a[x],e.cap-e.flow);
Q.push(e.to);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u=t; u!=s; u=edges[p[u]].from){
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
}
flow+=a[t];
}
return flow;
}
}WangLuoL;
int main()
{
int n,m;
while(~scanf("%d%d",&m,&n))
{
WangLuoL.init(n);
int from,to,cap;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&from,&to,&cap);
WangLuoL.AddEdge(from,to,cap);
}
printf("%d\n",WangLuoL.Maxflow(1,n));
}
return 0;
}
Dinic 算法:
hdu 3046 最小割 即为最大流:
将狼与源点连,羊与汇点连,容量都为无穷,将图的各个相邻点连接,容量为1
然后题目就转化成最小去掉多少条边使不连通,即求最小割最大流.
// File Name: 3046.cpp
// Author: Zlbing
// Created Time: 2013/9/10 20:41:04
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
const int MAXN=200*200+100;
struct Edge{
int from,to,cap,flow;
};
bool cmp(const Edge& a,const Edge& b){
return a.from < b.from || (a.from == b.from && a.to < b.to);
}
struct Dinic{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[MAXN];
bool vis[MAXN];
int d[MAXN];
int cur[MAXN];
void init(int n){
this->n=n;
for(int i=0;i<=n;i++)G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap){
edges.push_back((Edge){from,to,cap,0});
edges.push_back((Edge){to,from,cap,0});//当是无向图时,反向边容量也是cap,有向边时,反向边容量是0
m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS(){
CL(vis,0);
queue<int> Q;
Q.push(s);
d[s]=0;
vis[s]=1;
while(!Q.empty()){
int x=Q.front();
Q.pop();
for(int i=0;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow){
vis[e.to]=1;
d[e.to]=d[x]+1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x==t||a==0)return a;
int flow=0,f;
for(int& i=cur[x];i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
//当所求流量大于need时就退出,降低时间
int Maxflow(int s,int t,int need){
this->s=s;this->t=t;
int flow=0;
while(BFS()){
CL(cur,0);
flow+=DFS(s,INF);
if(flow>need)return flow;
}
return flow;
}
//最小割割边
vector<int> Mincut(){
BFS();
vector<int> ans;
for(int i=0;i<edges.size();i++){
Edge& e=edges[i];
if(vis[e.from]&&!vis[e.to]&&e.cap>0)ans.push_back(i);
}
return ans;
}
void Reduce(){
for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow;
}
void ClearFlow(){
for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;
}
};
Dinic solver;
int main()
{
int n,m;
int cas=0;
while(~scanf("%d%d",&n,&m))
{
int s=n*m;
int t=n*m+1;
int N=n*m+1;
solver.init(N);
int a;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&a);
if(i!=0)
solver.AddEdge((i-1)*m+j,i*m+j,1);
if(j!=0)
solver.AddEdge(i*m+j-1,i*m+j,1);
if(a==1)
solver.AddEdge(s,i*m+j,INF);
if(a==2)
solver.AddEdge(i*m+j,t,INF);
}
}
int ans=solver.Maxflow(s,t,INF);
printf("Case %d:\n",++cas);
printf("%d\n",ans);
}
return 0;
}