一般的な拡張方法はネットの最大の流れを求めます(Ford-Fulkersonアルゴリズム)
11782 ワード
/*
Time:2015-6-18
————Ford-Fulkerson
:
: 0 1 1 n 1
*/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
const int INF = 0x7fffffff;//
const int maxn = 1000 + 10;//
int n, m;
int flag[maxn], pre[maxn], alpha[maxn];
int c[maxn][maxn], f[maxn][maxn];
queue<int>Q;
int main()
{
int i, j, u, v, cc, ff;
scanf("%d%d", &n, &m);
for (i = 0; i<n; i++) for (j = 0; j<n; j++) c[i][j] = INF, f[i][j] = INF; //
for (i = 0; i<m; i++)
{
scanf("%d%d%d%d", &u, &v, &cc, &ff);// , , ,
//
if (c[u][v] == INF) { c[u][v] = cc; f[u][v] = ff; }
else { c[u][v] += cc; f[u][v] += ff; }
}
//0 n-1
int startt, endd;
startt = 0;
endd = n - 1;
while (1)
{
while (!Q.empty()) Q.pop();
memset(flag, -1, sizeof(flag));
memset(pre, -1, sizeof(pre));
memset(alpha, -1, sizeof(alpha));
flag[startt] = 0;//
pre[startt] = 0;//
alpha[startt] = INF;// INF
Q.push(startt);
while ((!Q.empty()) && flag[endd] == -1)
{
int h = Q.front(); Q.pop();
for (i = 0; i<n; i++)
{
//
if (c[h][i] != INF)//
{
if (f[h][i]<c[h][i])//
{
if (flag[i] == -1)//i
{
flag[i] = 0;//i
pre[i] = h;//i h
//alpha[i] alpha[h] c[h][i]-f[h][i]
if (c[h][i] - f[h][i] <= alpha[h]) alpha[i] = c[h][i] - f[h][i];
else alpha[i] = alpha[h];
Q.push(i);//i
}
}
}
//
if (c[i][h] != INF)//
{
if (f[i][h]>0)//
{
if (flag[i] == -1)//i
{
flag[i] = 0;//i
pre[i] = -h;//i h -
//alpha[i] alpha[h] f[i][h]
if (alpha[h] <= f[i][h]) alpha[i] = alpha[h];
else alpha[i] = f[i][h];
Q.push(i);//i
}
}
}
}
flag[h] = 1;//h ,
}
if (flag[endd] == -1 || alpha[endd] == 0) break; // ,
int a = alpha[endd];//
int now = endd;
while (1)
{
if (now == 0) break;
if (pre[now] >= 0)
{
f[pre[now]][now] += a;
now = pre[now];
}
else if (pre[now]<0)
{
f[now][-pre[now]] -= a;
now = -pre[now];
}
}
}
for (i = 0; i<n; i++)
for (j = 0; j<n; j++)
if (f[i][j] != INF)
printf("%d --> %d : %d
", i, j, f[i][j]);
int maxflow = 0;
for (i = 0; i<n; i++) if (f[0][i] != INF) maxflow += f[0][i];
printf("maxflow = %d
", maxflow);
return 0;
}