题目链接
一道比较基础的网络流。
超源点->插座->电器->超汇点
一开始是想得是统计每个插座的数量,以这个数量作为超源点对插座的权值,不过后来发现,只有每次都建议个权值为1的边就可以了。另外,因为转换器的供应是无限的,所以边权应该是inf。其余边权值是1。后跑一边Dinic。
下面是ac代码:
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstdlib>
#define ll long long
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 1e5+5;
map<string, int> mp;
int he[N], ver[N], ne[N];
int e[N], l[N];
int n, m, k;
int _cnt;
int tot;
void init()
{
memset(he, 0, sizeof(he));
mp.clear();
tot = 1;
_cnt = 2;
}
void add(int x, int y, int w)
{
ver[++tot] = y;
ne[tot] = he[x];
e[tot] = w;
he[x] = tot;
ver[++tot] = x;
ne[tot] = he[y];
e[tot] = 0;
he[y] = tot;
}
bool bfs(int s, int en)
{
memset(l, 0, sizeof(l));
queue<int> q;
q.push(s);
l[s] = 1;
while(q.size())
{
int u = q.front();
q.pop();
if (u == en) return 1;
for (int i = he[u]; i; i = ne[i])
{
int y = ver[i];
if (!l[y] && e[i])
{
l[y] = l[u] + 1;
q.push(y);
}
}
}
return 0;
}
int dfs(int u, int MaxFlow, int en)
{
if (u == en) return MaxFlow;
int uflow = 0;
for (int i = he[u]; i; i = ne[i])
{
int y = ver[i];
if (l[y] == l[u]+1 && e[i])
{
int flow = min(e[i], MaxFlow - uflow);
flow = dfs(y, flow, en);
e[i] -= flow;
e[i^1] += flow;
uflow += flow;
if (uflow == MaxFlow)
break;
}
}
if (uflow == 0)
l[u] = 0;
return uflow;
}
int Dinic()
{
int MaxFlow = 0;
while(bfs(0, 1))
MaxFlow += dfs(0, inf, 1);
return MaxFlow;
}
int main()
{
while(scanf("%d", &n) != EOF)
{
init();
for (int i = 0; i < n; i++)
{
string te;
cin >> te;
if (mp.find(te) == mp.end()) mp[te] = _cnt++;
add(0, mp[te], 1);
}
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
string ta, tb;
cin >> ta >> tb;
if (mp.find(ta) == mp.end()) mp[ta] = _cnt++;
if (mp.find(tb) == mp.end()) mp[tb] = _cnt++;
// cout << mp[tb] <<" " << mp[ta] <<" " << 1 <<endl;
add(mp[tb], mp[ta], 1);
// cout << mp[ta] <<" " << 1 <<" " << 1 <<endl;
add(mp[ta], 1, 1);
}
scanf("%d", &k);
for (int i = 0; i < k; i++)
{
string ta, tb;
cin >> ta >> tb;
if (mp.find(ta) == mp.end()) mp[ta] = _cnt++;
if (mp.find(tb) == mp.end()) mp[tb] = _cnt++;
// cout << mp[tb] <<" " << mp[ta] <<" " << inf <<endl;
add(mp[tb], mp[ta], inf);
}
// for (it=mp.begin(); it != mp.end(); it++)
// {
// cout << it->first <<" " << it->second <<endl;
// }
int ans = Dinic();
printf("%d\n", m - ans);
}
return 0;
}