bzoj3396 usaco total flow 题解 题解: 代码:

传送门

题解:

(根本不知道题目说那么多在干什么。。。误导人么。。。)

裸的最大流,不解释

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#define REP(i, a, b) for(int i = a; i <= b; i ++)
#define REPG(i, x) for(int i = head[x]; i; i = g[i].nxt)
#define clr(x, y) memset(x, y, sizeof(x));
using namespace std;
typedef long long LL;
typedef double LF;
LL (LL a, LL b){return a > b ? a : b;}
LL Min(LL a, LL b){return a < b ? a : b;}
LL abs(LL x){return x > 0 ? x : -x;}
const int MAXN = 1e3 + 15;
const int INF = 2e9;
struct Edge{int to, nxt, f;}g[MAXN << 1];
int head[MAXN], cur[MAXN], d[MAXN], cnt = -1, n, s, t, ans;
queue <int> q;
inline void add(int u, int v, int f){g[++ cnt] = (Edge){v, head[u], f}; head[u] = cnt;}
inline void add_edge(int u, int v, int f){add(u, v, f); add(v, u, 0);}
inline int read(){
int r = 0, z = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') z = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){r = r * 10 + ch - '0'; ch = getchar();}
return r * z;
}
bool bfs(){
clr(d, -1); q.push(s); d[s] = 1;
while(!q.empty()){
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = g[i].nxt){
int v = g[i].to;
if(g[i].f && d[v] == -1){
d[v] = d[u] + 1;
q.push(v);
}
}
}
return d[t] != -1;
}
int dfs(int u, int flow){
if(u == t) return flow;
int ret = 0;
for(int& i = cur[u]; ~i; i = g[i].nxt){
int v = g[i].to;
if(g[i].f && d[v] == d[u] + 1){
int tmp = dfs(v, min(flow, g[i].f));
g[i].f -= tmp; flow -= tmp;
g[i ^ 1].f += tmp; ret += tmp;
if(!flow) break;
}
}
if(!ret) d[u] = -1;
return ret;
}
void dinic(){
while(bfs()){
for(int i = 1; i <= 52; i ++) cur[i] = head[i];
ans += dfs(s, INF);
}
}
void work(){
clr(head, -1);
n = read(); s = 1, t = 26;
for(int i = 1; i <= n; i ++){
char ch[5]; int u, v, f;
scanf("%s", ch);
if(ch[0] >= 'A' && ch[0] <= 'Z') u = ch[0] - 'A' + 1;
else u = ch[0] - 'a' + 27;
scanf("%s", ch);
if(ch[0] >= 'A' && ch[0] <= 'Z') v = ch[0] - 'A' + 1;
else v = ch[0] - 'a' + 27;
f = read();
add_edge(u, v, f);
}
dinic();
printf("%dn", ans);
}
int main(){
work();
return 0;
}