A Plug for UNIX
题目大意:
n个插座,m个电器及其对应的插座,k个转化器,前一个插座可以转化为后一个插座,问最少有多少设备没有插座用,转换器数量不限
解题思路:
解决问题的难点还是在于建图,还有插座和转换器是字符串形式,用一个map存储:
源点------------- 容量为1 -------------------- > 电器
电器------------- 容量为1 -------------------- > 插座
插座------------- 容量为正无穷inf -------------------- > 转换后插座 //因为转换器不限量,可以多次使用该转换器
转换后插座------------- 容量为1 -------------------- > 汇点
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 10000;
const int maxm = 1000000;
struct poi {
int u, v, cap, cost, next;
}edge[maxm];
int head[maxn], cnt , dist[maxn], cur[maxn],vis[maxn];
int n, m, k , st, ed;
map<string, int>mp;
void init() {
memset(head, -1, sizeof(head));
// memset(edges, 0, sizeof(edges));
mp.clear();
cnt = 0;
st = 0;
}
void adde(int u, int v, int w) {
edge[cnt].u = u, edge[cnt].v = v,edge[cnt].cost=0, edge[cnt].cap = w;
edge[cnt].next = head[u], head[u] = cnt++;
edge[cnt].u = v, edge[cnt].v = u,edge[cnt].cost=0, edge[cnt].cap = 0;
edge[cnt].next = head[v], head[v] = cnt++;
}
void getmap(){
char s[30];
char str[30];
int ans=1;
while(n--){
scanf("%s", s);
mp[s]=ans++;
adde(0,mp[s],1);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%s%s", str, s);
mp[str]=ans++;
if(!mp[s]) mp[s]=ans++;
adde(mp[s],mp[str],1);
adde(mp[str],ed,1);
}
scanf("%d",&k);
while(k--){
scanf("%s%s", s, str);
if(!mp[s]) mp[s]=ans++;
if(!mp[str]) mp[str]=ans++;
adde(mp[str],mp[s],inf);
}
}
bool BFS(int st, int ed){
queue<int>q;
memset(vis, 0, sizeof(vis));
memset(dist, -1, sizeof(dist));
vis[st] = 1;
dist[st] = 0;
q.push(st);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next){
poi E = edge[i];
if(!vis[E.v] && E.cap > E.cost){
vis[E.v] = 1;
dist[E.v] = dist[u] + 1;
if(E.v == ed) return true;
q.push(E.v);
}
}
}
return false;
}
int DFS(int x, int ed, int a){
if(x == ed || a == 0)
return a;
int flow = 0, f;
for(int &i = cur[x]; i != -1; i = edge[i].next){
poi &E = edge[i];
if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.cost))) > 0){
E.cost += f;
edge[i ^ 1].cost -= f;
a -= f;
flow += f;
if(a == 0) break;
}
}
return flow;
}
int dinic(int st, int ed){
int flowsum = 0;
while(BFS(st, ed)){
memcpy(cur, head, sizeof(head));
flowsum += DFS(st, ed, inf);
}
return flowsum;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
while(scanf("%d", &n)!=EOF){
ed = n+m+k+1;
init();
getmap();
cout<<m-dinic(st,ed)<<endl;
}
return 0;
}