#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;
}
近期评论