uva753(一般图匹配)

/*
translation:
	一种设备插头对应着一个插座,但是有转换器可以将一种设备的插头转换成另外一种插头,每种转换器数量无限。
	求最后最少剩下多少个设备匹配不上。
	
solution:
	一般图的最大匹配。edmond-karp算法直接上。
	
note:
	注意这个不能套匈牙利,因为转换器的关系,插头之间还有边存在。不能算作二分图。
*/
#include 

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 edges;
vector 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 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 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;
}

你可能感兴趣的:(uva,OJ,网络流(最大流))