#include <stdio.h> #include<iostream> #define N 110 #define oo 1000000000 using namespace std; int n, m, source, sink; int G[N][N]; int pi[N]; int CurrentNode[N]; int queue[N]; int d[N]; int numbs[N]; int rev_BFS() { int i, j, head(0), tail(0); for(i = 1; i <= n; i++) numbs[d[i]=n] ++; numbs[n]--; d[sink] = 0; numbs[0]++; queue[ ++tail ] = sink; while( head != tail ) { i = queue[++head]; for(j = 1; j <= n; j++) { if(d[j]<n||G[j][i]==0)continue; queue[ ++tail ] = j; numbs[n]--; d[j]=d[i]+1; numbs[d[j]]++; } } return 0; } int Augment() { int i, j, tmp, width(oo); for(i = sink, j = pi[i]; i != source; i = j, j = pi[j]) { tmp = G[j][i]; if(tmp < width) width = tmp; } for(i = sink, j = pi[i]; i != source; i = j, j = pi[j]) { G[j][i] -= width; G[i][j] += width; } return width; } int Retreat(int &i) { int tmp; int j, mind(n-1); for(j=1; j <= n; j++) if(G[i][j] > 0 && d[j] < mind) mind = d[j]; tmp = d[i]; numbs[d[i]]--; d[i] = 1 + mind; numbs[d[i]]++; if( i != source ) i = pi[i]; return numbs[tmp]; } int find_max_flow() { int flow(0), i, j; rev_BFS(); for(i=1; i<=n; i++) CurrentNode[i] = 1; i = source; for( ; d[source] < n ; ) { for(j = CurrentNode[i]; j <= n; j++) if( G[i][j] > 0 && d[i] == d[j] + 1 ) break; if( j <= n ) { CurrentNode[i] = j; pi[j] = i; i = j; if( i == sink ) { flow += Augment(); i = source; } } else { CurrentNode[i] = 1; if(Retreat(i)==0) break; } } return flow; } int main() { int i,j,k,u,v,w,np,nc; while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF) { memset(G,0,sizeof(G)); for(i=1;i<=m;++i) { scanf(" (%d,%d)%d",&v,&u,&w); G[v+1][u+1]+=w; } for(i=1;i<=np;++i) { scanf(" (%d)%d",&u,&w); G[n+2][u+1]=w; } for(i=1;i<=nc;++i) { scanf(" (%d)%d",&v,&w); G[v+1][n+1]=w; } source=n+2;sink=n+1; n+=2; printf("%d\n", find_max_flow()); } return 0; }
鄰接矩陣應該都會自己改吧,本題是POJ 1459 的,效果誰用誰知道。。。
應廣大農民要求,寫了一個鄰接表版本的(未加rev_bfs),很簡短:
#include <cstdio>
#include <cstring>
const int maxn = 201;
const int maxm = 201;
const int oo = ~0U >> 1;
int cu[maxn],pi[maxn],head[maxn],num[maxn],d[maxn],g[maxm*2],e[maxm*2],next[maxm*2];
int source,sink,n,m;
int agument()
{
int i,j,p,min = oo;
for (i = sink,j = pi[i]; i != source; i = j,j = pi[i])
{
p = cu[j];
if (g[p] < min) min = g[p];
}
for (i = sink,j = pi[i]; i != source; i = j,j = pi[i])
{
p = cu[j];
g[p] -= min;
g[p-1+(p&1)*2] += min;
}
return min;
}
int retreat(int &x)
{
int mind = n-1,tmp,p;
for (p = head[x]; p > 0; p = next[p]) if (d[e[p]] < mind && g[p] > 0) mind = d[e[p]];
tmp = d[x];
--num[d[x]];
d[x] = mind+1;
++num[d[x]];
if (x != source) x = pi[x];
return num[tmp];
}
int find_maxflow()
{
int i,j,p,ans = 0;
// rev_bfs();
num[0] = n;
for (i = 1; i <= n; ++i) cu[i] = head[i];
i = source;
while (d[source] < n)
{
for (j = cu[i]; j != 0 ; j = next[j]) if (g[j] != 0 && d[i] == d[e[j]]+1) break;
if (j != 0)
{
cu[i] = j; j = e[j]; pi[j] = i; i = j;
if (i == sink)
{
ans += agument();
i = source;
}
}
else
{
cu[i] = head[i];
if (retreat(i) == 0) break;
}
}
return ans;
}
int main()
{
int i,j,k,l;
// freopen("1273.in","r",stdin);
// freopen("1273.out","w",stdout);
while (~scanf("%d%d",&m,&n))
{
memset(cu,0,sizeof(cu));
memset(pi,0,sizeof(pi));
memset(head,0,sizeof(head));
memset(num,0,sizeof(num));
memset(d,0,sizeof(d));
memset(g,0,sizeof(g));
memset(e,0,sizeof(e));
memset(next,0,sizeof(next));
for (i = 1; i <= m; ++i)
{
scanf("%d%d%d",&j,&k,&l);
e[i*2-1] = k;
e[i*2 ] = j;
next[i*2-1] = head[j];
next[i*2 ] = head[k];
head[j] = i*2-1;
head[k] = i*2 ;
g[i*2-1] = l;
g[i*2 ] = 0;
}
source = 1;
sink = n;
printf("%d\n",find_maxflow());
}
return 0;
}