Description
Input
第1行输入N,之后N行每行描述一条水管,前两个英文字母表示水管的两端(大小写字母是不一样的),后一个整数表示水管的流量,流量不会超过1000.
Output
一个整数,表示总流量.
Sample Input
5
A B 3
B C 3
C D 5
D Z 4
B Z 6
Sample Output
3
HINT
Source
Silver
用来练习网络流的模板题。
专属于权限的水题。
#include <bits/stdc++.h>
#define inf 0x7f7f7f7f
#define N 510
#define M 50010
using namespace std;
struct Edge
{
int next, to, v;
}e[M];
int head[N], n, m, cnt = 1, cur[N], h[N], q[M], ans, T;
void ins(int u, int v, int w)
{
e[++ cnt].to = v;
e[cnt].next = head[u];
e[cnt].v = w;
head[u] = cnt;
}
inline int read()
{
int x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
void insert(int u, int v, int w)
{
ins(u, v, w);
ins(v, u, 0);
}
int bfs()
{
int t = 0, w = 1;
memset(h, -1, sizeof(h));
h[1] = 0;
q[0] = 1;
while(t != w)
{
int now = q[t ++];
if(t == M) t = 0;
for(int i = head[now]; i; i = e[i].next)
{
int y = e[i].to;
if(h[y] == -1 && e[i].v)
{
h[y] = h[now] + 1;
q[w ++] = y;
if(w == M) w = 0;
}
}
}
if(h[T] == -1) return 0;
else return 1;
}
int dfs(int x, int f)
{
if(x == T) return f;
int used = 0, w;
for(int i = cur[x]; i; i = e[i].next)
{
int y = e[i].to;
if(h[y] == h[x] + 1 && e[i].v)
{
w = dfs(y, min(e[i].v, f - used));
used += w;
e[i].v -= w;
if(e[i].v) cur[x] = i;
e[i ^ 1].v += w;
if(used == f) return f;
}
}
if(!used) h[x] = -1;
return used;
}
void dinic()
{
while(bfs())
{
for(int i = 0; i <= 60; i ++)
cur[i] = head[i];
ans += dfs(1, inf);
}
}
int main()
{
n = read();
T = 26;
for(int i = 1; i <= n; i ++)
{
char ch[5];
int a,b;
scanf("%s",ch);
if(ch[0] >= 'A' && ch[0] <= 'Z') a = ch[0] - 'A' + 1;
else a = ch[0] - 'a' + 27;
scanf("%s",ch);
if(ch[0] >= 'A' && ch[0] <= 'Z') b = ch[0] - 'A' + 1;
else b = ch[0] - 'a' + 27;
int x = read();
insert(a,b,x);
}
dinic();
printf("%d",ans);
return 0;
}