http://poj.org/problem?id=1273
//EK算法
#include "stdio.h"
#include "queue"
using namespace std;
const int maxn = 205;
int map[maxn][maxn],path[maxn]; //邻接数组 前驱数组
int n,m;
bool EK_Bfs( int start,int end ) //广搜增广路
{
int i,j;
queue<int>que; //广搜队列
bool vis[maxn]={false};
for( i=1;i<=m;i++ )
path[i] = -1;
que.push( start );
vis[start] = true;
while( !que.empty() )
{
int e = que.front();
if( e==end ) //当队头弹出的点为终点时 即可判断广路找到
return true;
que.pop();
for( i=1; i<=m; i++ )
{
if( map[e][i] && !vis[i] ) //当边容量为非空 且增广点未标记
{
vis[i] = true;
path[i] = e; //记录前驱
que.push(i); //入队
}
}
}
return false;
}
int EK_Max_Flow( int st,int end ) //起点 终点
{
int k,min,ans=0;
while( EK_Bfs( st,end ) ) //当增广成功
{
min = 1<<30;
k = end;
while( path[k] != -1 ) //寻找瓶颈
{
min = min < map[path[k]][k] ? min : map[path[k]][k];
k = path[k];
}
ans += min; //累加最大流
k = end;
while( path[k] != -1 ) //修改路径上的边容量
{
map[path[k]][k] -= min;
map[k][path[k]] += min;
k = path[k];
}
}
return ans;
}
int main()
{
int i,j,a,b,c;
while( scanf("%d%d",&n,&m)==2 )
{
for( i=1;i<=m;i++ )
for( j=1;j<=m;j++ )
map[i][j] = 0;
for( i=1;i<=n;i++ )
{
scanf("%d%d%d",&a,&b,&c); //可能出现重边 要用+=
map[a][b] += c;
}
int ans = EK_Max_Flow(1, m);
printf("%d\n",ans);
}
return 0;
}
//Dinic
#include "stdio.h"
#include "queue"
#include "string.h"
#include "vector"
#include "algorithm"
using namespace std;
const int maxn = 205;
const int inf = 1<<30;
int n,m;
int cap[maxn][maxn];
int dis[maxn],vis[maxn];
bool Dinic_Bfs( int st,int end ) //BFS分层
{
memset( vis,0,sizeof(vis) );
memset( dis,0,sizeof(dis) );
queue<int>que;
dis[st] = 0; vis[st] = true;
que.push(st);
while( !que.empty() )
{
int u = que.front(); que.pop();
if( u == end ) //分层到汇点就结束
return true;
for( int v = 1; v <= n; v ++ )
{
if( !vis[v] && cap[u][v] )
{
vis[v] = true;
dis[v] = dis[u] + 1;
que.push( v );
}
}
}
return false;
}
int Dinic_Dfs( int st,int maxf,int end ) //沿BFS的分层增广
{
int ans = 0,flow;
if( st == end )
return maxf;
for( int i = 1; i <= n; i ++ )
{
if( cap[st][i] && dis[i] == dis[st] + 1 ){
flow = Dinic_Dfs( i,cap[st][i]<maxf?cap[st][i]:maxf,end); //i点能流走的流量
cap[st][i] -= flow; //增广
cap[i][st] += flow;
ans += flow;
maxf -= flow;
if( !maxf )
return ans;
}
}
if( !ans ) //注意没得流的时候要标记为-1
dis[st] = -1;
return ans;
}
int Dinic( int st,int end )
{
int ans = 0;
while( Dinic_Bfs(st,end) ){ //分层
ans += Dinic_Dfs( st,inf,end ); //增广
}
return ans;
}
int main()
{
//freopen("data.txt","r",stdin);
int a,b,c;
while( scanf("%d%d",&m,&n) != EOF ){
memset( cap,0,sizeof(cap) );
for( int i = 1; i <= m; i ++ ){
scanf("%d%d%d",&a,&b,&c);
cap[a][b] += c;
}
printf("%d\n",Dinic(1,n));
}
return 0;
}
#include "stdio.h"
#include "queue"
using namespace std;
const int maxn = 205;
const int inf = 1<<30;
int dis[maxn];
bool vis[maxn];
int n,m,pos;
struct Node
{
int id,w,pos;
Node *next;
}node[maxn*10];
struct Head
{
Node *first;
}head[maxn];
void add(int a,int b,int c)
{
node[pos].id = b; node[pos].w = c; node[pos].pos = pos;
node[pos].next = head[a].first;
head[a].first = &node[pos];
pos++;
node[pos].id = a; node[pos].w = 0; node[pos].pos = pos;
node[pos].next = head[b].first;
head[b].first = &node[pos];
pos++;
}
bool dinic_bfs( int start,int end )
{
Node *p;
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
vis[start] = true;
dis[start] = 0;
queue<int>q;
q.push(start);
while( !q.empty() )
{
int e = q.front();
q.pop();
if( e==end )
return true;
for( p = head[e].first; p!=NULL; p=p->next )
{
if( !vis[p->id] && p->w )
{
vis[p->id] = true;
q.push( p->id );
dis[p->id] = dis[e] + 1;
}
}
}
return false;
}
int dinic_dfs( int start,int maxf,int end )
{
if( start==end )
return maxf;
int ans = 0,flow;
for( Node *p=head[start].first; p!=NULL; p=p->next )
{
if( dis[p->id] == dis[start] + 1 )
{
flow = dinic_dfs( p->id,p->w < maxf?p->w:maxf,end );
ans += flow;
maxf -= flow;
p->w -= flow;
node[p->pos^1].w +=flow;
if( maxf==0 )
break;
}
}
return ans;
}
int Dinic( int start,int end )
{
int ans = 0;
while( dinic_bfs( start,end ) )
ans += dinic_dfs( start, inf ,end );
return ans;
}
int main()
{
int i,j,a,b,c;
while( scanf("%d%d",&n,&m)==2 )
{
pos = 0;
for( i=1; i<=m; i++ )
{
head[i].first = NULL;
}
for( i=1; i<=n; i++ )
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
int ans = Dinic(1,m);
printf("%d\n",ans);
}
return 0;
}
//SAP
#include "stdio.h"
#include "queue"
#include "string.h"
#include "vector"
#include "algorithm"
using namespace std;
const int maxn = 205;
const int inf = 1<<30;
int n,m;
int cap[maxn][maxn];
int pre[maxn],level[maxn],gap[maxn]; //前驱 距离标号 gap常数优化
int SAP( int st,int end )
{
memset( pre,-1,sizeof(pre) );
memset( level,0,sizeof(level) );
memset( gap,0,sizeof(gap) );
gap[0] = n+1;
int v,u = pre[st] = st,maxf = 0,aug = inf;
while( level[st] < n+1 ){
for( v = 1; v <= n; v ++ ){
if( cap[u][v] && level[u] == level[v] + 1 )
break;
}
if( v <= n ){
pre[v] = u;
u = v;
if( v == end ){
aug = inf;
for( int i = v; i != st; i = pre[i] )
if( aug > cap[pre[i]][i] )
aug = cap[pre[i]][i];
maxf += aug;
for( int i = v; i != st; i = pre[i] ){
cap[pre[i]][i] -= aug;
cap[i][pre[i]] += aug;
}
u = st;
}
}
else{
int minlevel = n;
for( v = 1; v <= n; v ++ )
if( cap[u][v] > 0 && minlevel > level[v] )
minlevel = level[v];
gap[level[u]] --;
if( !gap[level[u]] )
break;
level[u] = minlevel + 1;
gap[level[u]] ++;
u = pre[u];
}
}
return maxf;
}
int main()
{
//freopen("data.txt","r",stdin);
int a,b,c;
while( scanf("%d%d",&m,&n) != EOF ){
memset( cap,0,sizeof(cap) );
for( int i = 1; i <= m; i ++ ){
scanf("%d%d%d",&a,&b,&c);
cap[a][b] += c;
}
printf("%d\n",SAP(1,n));
}
return 0;
}
#include "stdio.h"
#include "queue"
#include "algorithm"
using namespace std;
const int maxn = 210;
const int inf = 1<<30;
int n,m,pos;
struct Node
{
int v,w,next;
Node() {};
Node( int v,int w,int next ):v(v),w(w),next(next) {}
}node[100*maxn];
int head[maxn];
void add( int u,int v,int w )
{
node[pos] = Node(v,w,head[u]);
head[u] = pos ++;
node[pos] = Node(u,0,head[v]);
head[v] = pos ++;
}
int ISAP( int st,int end )
{
int curedge[maxn],pre[maxn],h[maxn],gap[maxn];
int u,neck,tmp,i;
memset( h,0,sizeof(h) );
memset( gap,0,sizeof(gap) );
int cur_flow,flow_ans = 0;
for( int i = 1; i <= n; i ++ )
curedge[i] = head[i];
gap[0] = n;
u = st;
while( h[st] < n )
{
if( u == end )
{
cur_flow = inf;
for( i = st; i != end; i = node[curedge[i]].v )
{
if( cur_flow > node[curedge[i]].w )
{
neck = i;
cur_flow = node[curedge[i]].w;
}
}
for( i = st; i != end; i = node[curedge[i]].v )
{
tmp = curedge[i];
node[tmp].w -= cur_flow;
node[tmp^1].w += cur_flow;
}
flow_ans += cur_flow;
u = neck;
}
for( i = curedge[u]; i != -1; i = node[i].next )
{
if( node[i].w && h[u] == h[node[i].v] + 1 )
break;
}
if( i != -1 )
{
curedge[u] = i;
pre[node[i].v] = u;
u = node[i].v;
}
else
{
if( 0 == --gap[h[u]] )
break;
curedge[u] = head[u];
for( tmp = n,i = head[u]; i != -1; i = node[i].next )
if( node[i].w )
tmp = tmp < h[node[i].v]?tmp:h[node[i].v];
h[u] = tmp + 1;
gap[h[u]] ++;
if( u != st )
u = pre[u];
}
}
return flow_ans;
}
int main()
{
//freopen("data.txt","r",stdin);
char ch;
int u,v,w;
while( scanf("%d%d",&m,&n) == 2 )
{
memset(head,-1,sizeof(head));
for( int i = 1; i <= m; i ++ )
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
printf("%d\n",ISAP(1,n));
}
return 0;
}