原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549
最大流入门题:最大流问题在刘汝佳的《算法竞赛入门经典》和《算法竞赛入门经典训练指南》中均有纤细介绍。
竞赛中通常可以使用Dinic算法和ISAP算法,但是Ford-Fulkerson算法理解起来简单一点。
最大流问题吧算法代码当做模板,根据具体问题去建图就可以了。
AC代码1.Ford-Fulkerson算法
#include
#include
#include
#include
#include
using namespace std;
const int maxn=20;
const int maxm=1050;
const int INF=0x3f3f3f3f;
int t;
int n,m;
bool vis[maxn];
int Case=0;
struct node
{
int to,cap;
unsigned int rev;
};
vector G[maxn];
void add_edge(int from,int to,int cap)
{
G[from].push_back({to,cap,G[to].size()});
G[to].push_back({from,0,G[from].size()-1});
}
int dfs(int v,int t,int f)
{
if(v==t) return f;
vis[v]=true;
for(unsigned int i=0;i0)
{
int d=dfs(e.to,t,min(f,e.cap));
if(d>0)
{
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)
{
int flow=0;
while(1)
{
memset(vis,0,sizeof(vis));
int f=dfs(s,t,INF);
if(f==0) return flow;
flow+=f;
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) G[i].clear();
for(int i=0;i
/**
* 行有余力,则来刷题!
* 博客链接:http://blog.csdn.net/hurmishine
* 个人博客网站:http://wuyunfeng.cn/
*/
#include
#include
#include
#include
#include
using namespace std;
const int maxn=15+5;
const int INF=0x3f3f3f3f;
struct Edge
{
int from,to,cap,flow;//起点,终点,容量,流量
Edge(){}
Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}
};
struct Dinic
{
int n,m,s,t; //节点数,边数(包括反向弧),源点编号和汇点编号
vectoredge; //边表。edge[e]和edge[e^1]互为反向弧
vectorG[maxn]; //邻接表,G[i][j]表示节点i的第j条边在数组中的序号
bool vis[maxn]; //BFS使用,标记一个节点是否被遍历过
int d[maxn]; //从起点到i点的距离
int cur[maxn]; //当前弧下标
void init(int n,int s,int t)
{
this->n=n;
this->s=s;
this->t=t;
for(int i=1;i<=n;i++)
G[i].clear();
edge.clear();
}
void addEdge(int from,int to,int cap)
{
//edge.push_back((Edge){from,to,cap,0});
//edge.push_back((Edge){to,from,0,0});
edge.push_back( Edge(from,to,cap,0) );
edge.push_back( Edge(to,from,0,0) );
m=edge.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS()
{
memset(vis,0,sizeof(vis));
queueq;//
q.push(s);
d[s]=0;
vis[s]=true;
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;ie.flow)//只考虑残量网络中的弧
{
vis[e.to]=true;
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];i0)
{
e.flow+=f;
edge[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)
break;
}
}
return flow;
}
int MaxFlow()
{
int flow=0;
while(BFS())
{
memset(cur,0,sizeof(cur));
flow+=DFS(s,INF);
}
return flow;
}
}Dinic;
int main()
{
//freopen("C:\\Users\\hncu_acm\\Desktop\\data.txt","r",stdin);
int T,n,m;
int kase=0;
cin>>T;
while(T--)
{
cin>>n>>m;
Dinic.init(n,1,n);
int u,v,w;
while(m--)
{
cin>>u>>v>>w;
Dinic.addEdge(u,v,w);
}
printf("Case %d: %d\n",++kase,Dinic.MaxFlow());
}
return 0;
}
//http://blog.csdn.net/x920405451x/article/details/39747081
#include
#include
#include
#include
#include
#include
#include
#include
#include
http://blog.csdn.net/x920405451x/article/details/39747081
http://acm.hdu.edu.cn/discuss/problem/post/reply.php?postid=31339&messageid=1&deep=0