http://acm.hdu.edu.cn/showproblem.php?pid=3549
邻接矩阵实现FF算法
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=16;
int map[maxn][maxn];
bool used[16*16];
int n,m,a,b,c;
int dfs(int s,int e,int f){
if(s==e) return f;
used[s]=true;
for(int i=1;i<=n;i++){
if(!used[i]&&map[s][i]>0){
int d=dfs(i,e,min(map[s][i],f));
if(d>0){
map[s][i]-=d;
map[i][s]+=d;
return d;
}
}
}
return 0;
}
int max_flow(){
int maxx=0;
while(1){
memset(used,0,sizeof(used));
int r=dfs(1,n,0x3f3f3f3f);
if(!r)
return maxx;
maxx+=r;
}
}
int main(){
int t;
cin>>t;
int k=1;
while(t--){
cin>>n>>m;
memset(map,0,sizeof(map));
for(int i=0;i<m;i++){
cin>>a>>b>>c;
map[a][b]+=c;
}
cout<<"Case "<<k++<<": "<<max_flow()<<endl;
}
}
邻接表实现FF算法
#include <bits/stdc++.h>
using namespace std;
const int MAX_V=16;
const int INF=0x3f3f3f3f;
struct edge{
int to,cap,rev;//rev用于确定反向边:反向边为G[to][rev]
edge(int to,int cap,int rev){
this->to=to; this->cap=cap; this->rev=rev;
}
};
vector<edge>G[MAX_V];
bool used[MAX_V];
void add_edge(int from,int to,int cap){
G[from].push_back(edge(to,cap,G[to].size()));//G[t].size(): (from,to)的反向边位于 to行G[to].size()列
G[to].push_back(edge(from,0,G[from].size()-1));//G[from].size()-1: (to,from)的反向边位于 from行G[from].size()-1列
}
int dfs(int v,int t,int f){
if(v==t) return f;
used[v]=true;
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(!used[e.to]&&e.cap>0){
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(used,0,sizeof(used));
int f=dfs(s,t,INF);
if(f==0) return flow;
flow+=f;
}
}
int main(){
int t,n,m;
cin>>t;
int k=1;
while(t--){
cin>>n>>m;
for(int i=1;i<=MAX_V;i++)
G[i].clear();
int a,b,c;
for(int i=1;i<=m;i++){
cin>>a>>b>>c;
add_edge(a,b,c);
}
cout<<"Case "<<k++<<": "<<max_flow(1,n)<<endl;
}
}
邻接矩阵实现EK算法
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int n,m,a,b,c;
int map[16][16];
bool used[16*16];
int pre[16*16];
bool bfs(){
memset(used,false,sizeof(used));
memset(pre,0,sizeof(pre));
queue<int>que;
que.push(1);
used[1]=true;
pre[1]=1;
while(que.size()){
int f=que.front();
que.pop();
for(int i=2;i<=n;i++){
if(map[f][i]>0&&!used[i]){
pre[i]=f;
used[i]=true;
if(i==n) return true;
que.push(i);
}
}
}
return false;
}
int max_flow(){
int maxx=0;
while(bfs()){
int d=0x3f3f3f3f;
for(int i=n;i!=1;i=pre[i])
d=min(d,map[pre[i]][i]);
for(int i=n;i!=1;i=pre[i]){
map[pre[i]][i]-=d;
map[i][pre[i]]+=d;
}
maxx+=d;
}
return maxx;
}
int main(){
int t;
cin>>t;
int k=1;
while(t--){
cin>>n>>m;
memset(map,0,sizeof(map));
for(int i=0;i<m;i++){
cin>>a>>b>>c;
map[a][b]+=c;
}
cout<<"Case "<<k++<<": "<<max_flow()<<endl;
}
}
邻接表实现dinic算法
#include <bits/stdc++.h>
using namespace std;
const int MAX_V=16;
const int INF=0x3f3f3f3f;
struct edge{
int to,cap,rev;//rev用于确定反向边:反向边为G[to][rev]
edge(int to,int cap,int rev){
this->to=to; this->cap=cap; this->rev=rev;
}
};
vector<edge>G[MAX_V];
int level[MAX_V];//顶点到源点的距离标号
int iter[MAX_V];//当前弧,在其之前的边已经用过了
void add_edge(int from,int to,int cap){
G[from].push_back(edge(to,cap,G[to].size()));//G[t].size(): (from,to)的反向边位于 to行G[to].size()列
G[to].push_back(edge(from,0,G[from].size()-1));//G[from].size()-1: (to,from)的反向边位于 from行G[from].size()-1列
}
void bfs(int s){
memset(level,-1,sizeof(level));
queue<int>que;
level[s]=0;
que.push(s);
while(!que.empty()){
int v=que.front(); que.pop();
for(int i=0;i<G[v].size();i++){
edge &e=G[v][i];
if(e.cap>0&&level[e.to]<0){
level[e.to]=level[v]+1;
que.push(e.to);
}
}
}
}
int dfs(int v,int t,int f){
if(v==t) return f;
for(int &i=iter[v];i<G[v].size();i++){//使用&增大iter[v]的值
edge &e=G[v][i];
if(e.cap>0&&level[v]<level[e.to]){
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){
bfs(s);
if(level[t]<0) return flow;
memset(iter,0,sizeof(iter));
int f;
while((f=dfs(s,t,INF))>0){
flow+=f;
}
}
}
int main(){
int t,n,m;
cin>>t;
int k=1;
while(t--){
cin>>n>>m;
for(int i=1;i<=MAX_V;i++)
G[i].clear();
int a,b,c;
for(int i=1;i<=m;i++){
cin>>a>>b>>c;
add_edge(a,b,c);
}
cout<<"Case "<<k++<<": "<<max_flow(1,n)<<endl;
}
}