?? 最大流 增廣路(xd).txt
字號:
#include <stdio.h>
#include <math.h>
#include <memory.h>
int n, np, nc, m, s, t;
int fa[104], q[104], f[104][104], c[104][104];
// 用fa記錄增廣路,q是求增廣路中所需要用的隊列,f,c是采用鄰接矩陣的方式來記錄網絡中的流量和容量
void proc()
{
int qs, qt, d, d0, i, j, ans = 0;
fa[t] = 1;
while (fa[t] != 0)
{
qs = 0; qt = 1; //隊列的首尾指針初始化
q[qt] = s;
memset(fa, 0, sizeof(fa)); //增廣路徑初始化
fa[s] = s;
while (qs < qt && fa[t] == 0) //若沒有找到到匯點的增廣路或還可以繼續尋找增廣路
{
i = q[++qs];
for (j = 1; j <= t; j++)
if (fa[j] == 0) //點j沒有標記過
if (f[i][j] < c[i][j]) //(i,j)的流量小于容量:存在一條(i,j)的前向弧
{
fa[j] = i;
q[++qt] = j;
}
else
if (f[j][i] > 0) //(j,i)的流量大于0,存在一條(j,i)的后向弧
{
fa[j] = -i;
q[++qt] = j;
}
}
if (fa[t] != 0) //如果找到一條從源點到匯點的增廣路就改進當前流
{
d0 = 10000000;
i = t;
while (i != s) //尋找最大的可改進量
{
if (fa[i] > 0)
{
if ((d = c[fa[i]][i] - f[fa[i]][i]) < d0)
d0 = d;
}
else
if (f[i][-fa[i]] < d0)
d0 = f[i][-fa[i]];
i = abs(fa[i]);
}
ans += d0; //總流量累加
i = t;
while (i != s) //改進流
{
if (fa[i] > 0)
f[fa[i]][i] += d0;
else
f[i][-fa[i]] -= d0;
i = abs(fa[i]);
}
}
}
printf("%d\n", ans); //輸出最大流
}
void main()
{
int i, u, v, cc;
while (scanf("%d%d%d%d", &n, &np, &nc, &m) == 4)
{
s = n + 2; t = n + 1; //以下是構圖
memset(f, 0, sizeof(f));
memset(c, 0, sizeof(c));
for (i = 1; i <= m; i++) //對于原圖中邊(u,v)連一條容量為cc的弧
{
while (getchar() != '(');
scanf("%d,%d)%d", &u, &v, &cc);
c[u + 1][v + 1] = cc;
}
for (i = 1; i <= np; i++) //對于PowerStation從源點連一條容量為cc的弧
{
while (getchar() != '(');
scanf("%d)%d", &u, &cc);
c[s][u + 1] = cc;
}
for (i = 1; i <= nc; i++) //對于Consumer連一條容量為cc的弧到匯點
{
while (getchar() != '(');
scanf("%d)%d", &u, &cc);
c[u + 1][t] = cc;
}
proc(); //求最大流
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -