#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;
}