uva753(一般图匹配)

来源:互联网 发布:易语言盗号源码2016 编辑:程序博客网 时间:2024/05/20 14:42
/*translation:一种设备插头对应着一个插座,但是有转换器可以将一种设备的插头转换成另外一种插头,每种转换器数量无限。求最后最少剩下多少个设备匹配不上。solution:一般图的最大匹配。edmond-karp算法直接上。note:注意这个不能套匈牙利,因为转换器的关系,插头之间还有边存在。不能算作二分图。*/#include <bits/stdc++.h>using namespace std;const int maxn = 600 + 5;const int INF = 1e30;struct Edge {  int from, to, cap, flow;  Edge(int u, int v, int c, int f):from(u),to(v),cap(c),flow(f) {}};int n;vector<Edge> edges;vector<int> G[maxn];int a[maxn];//起点到i的可改进量int p[maxn];//最短路上的p的入弧编号int recepter[maxn], device[maxn];int recepters, devices, adapters;void init(int n) {edges.clear();for(int i = 0; i < n; i++)G[i].clear();}void addEdge(int from, int to, int cap) {edges.push_back(Edge(from, to, cap, 0));edges.push_back(Edge(to, from, 0, 0));int len = edges.size();G[from].push_back(len - 2);G[to].push_back(len - 1);}int ek(int s, int t) {int flow = 0;for(;;) {queue<int> q;memset(a, 0, sizeof(a));q.push(s);a[s] = INF;while(!q.empty()) {int x = q.front();q.pop();for(int i = 0; i < G[x].size(); i++) {Edge& e = edges[G[x][i]];if(!a[e.to] && e.cap > e.flow) {p[e.to] = G[x][i];a[e.to] = min(a[x], e.cap - e.flow);q.push(e.to);}}if(a[t])break;}if(!a[t])break;//无法继续增广for(int i = t; i != s; i = edges[p[i]].from) {edges[p[i]].flow += a[t];edges[p[i] ^ 1].flow -= a[t];}flow += a[t];}return flow;}vector<string> ids;int ID(string str) {    int len = ids.size();    for(int i = 0; i < len; i++)        if(ids[i] == str)   return i;    ids.push_back(str);    return len; //返回下标}int main(){//freopen("in.txt", "r", stdin);    int T;    cin >> T;    while(T--) {init(maxn);ids.clear();memset(p, 0, sizeof(p));        string str, name, s1, s2;        cin >> recepters;        for(int i = 0; i < recepters; i++) {cin >> str;recepter[i] = ID(str);        }        cin >> devices;        for(int i = 0; i < devices; i++) {cin >> name >> str;device[i] = ID(name);addEdge(device[i], ID(str), 1);        }        cin >> adapters;        for(int i = 0; i < adapters; i++) {cin >> s1 >> s2;addEdge(ID(s1), ID(s2), INF);        }        int s = ids.size();        int t = s + 1;        for(int i = 0; i < devices; i++) {addEdge(s, device[i], 1);        }        for(int i = 0; i < recepters; i++) {addEdge(recepter[i], t, 1);        }        printf("%d\n", devices - ek(s, t));        if(T)printf("\n");    }    return 0;}

0 0
原创粉丝点击