uva 753 A Plug for UNIX 增广路求最大流

用map<string, int>为每一个插座,插头,设备指定一个编号u,先把源点与所有设备,设备与对应的插头,插座与汇点连起来,这些弧的容量为1,然后把转化器加进来,转化器相连的两个东西间加弧,容量为inf,然后用ek模板求最大流。

我的源点设为了0,汇点设为了500,(汇点要设大一些,否则可能会与插座插头等的编号重复),inf为0x3f3f3f3f。

#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map> 
#define inf 0x3f3f3f3f
using namespace std;

typedef struct Edge{
	int from, to, cap, flow;
	Edge(int a=0, int b=0, int c=0, int d=0):from(a), to(b), cap(c), flow(d){}
}Edge;

vector<Edge> edge;
vector<int> G[550];
map<string, int> mp;
int ncz, nct, nzh;
int a[100000];
int p[100000];

void init()
{
	for(int i = 0; i < 501; i++)
		G[i].clear();
	edge.clear();
}

int ek()
{
	int flow = 0;
	for(;;)
	{
		memset(a, 0, sizeof(a));
		queue<int> que;
		que.push(0);
		a[0] = inf;
		while(!que.empty())
		{
			int x = que.front();
			que.pop();
			for(int i = 0; i < G[x].size(); i++)
			{
				Edge& e = edge[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);
					que.push(e.to);
				}
			}
			if(a[500])	break;
		}
		if(!a[500]) break;
		for(int u = 500; u != 0; u = edge[p[u]].from)
		{
			edge[p[u]].flow += a[500];
			edge[p[u]^1].flow -= a[500];
		}
		flow += a[500];
	}
	return flow;
}
			
int main()
{
	//freopen("ztest.txt","r",stdin);
	//freopen("zans.txt","w",stdout);
	int tt;
	scanf("%d", &tt);
	while(tt--)
	{
		mp.clear();
		init();
		scanf("%d", &ncz);
		int m;
		int u = 1;
		for(int i = 0; i < ncz; i++)
		{
			string temp;
			int t;
			cin >> temp;
			if(!mp.count(temp))
				mp[temp] = u++;
			t = mp[temp];
			//printf("%d %c\n",temp,temp);
			edge.push_back(Edge(t, 500, 1, 0));
			edge.push_back(Edge(500, t, 0, 0));
			m = edge.size();
			G[t].push_back(m-2);
			G[500].push_back(m-1);
		}
		scanf("%d", &nct);
		for(int i = 0; i < nct; i++)
		{
			string str1;
			string str2;
			int t1;
			int t2;
			cin >> str1 >> str2;
			if(!mp.count(str1))	mp[str1] = u++;
			if(!mp.count(str2)) mp[str2] = u++;
			t1 = mp[str1];
			t2 = mp[str2];
			edge.push_back(Edge(0, t1, 1, 0));
			edge.push_back(Edge(t1, 0, 0, 0));
			edge.push_back(Edge(t1, t2, 1, 0));
			edge.push_back(Edge(t2, t1, 0, 0));
			m = edge.size();
			G[0].push_back(m-4);
			G[t1].push_back(m-3);
			G[t1].push_back(m-2);
			G[t2].push_back(m-1);
		}
		scanf("%d", &nzh);
		for(int i = 0; i < nzh; i++)
		{
			string str1;
			string str2;
			int t1;
			int t2;
			cin >> str1 >> str2;
			if(!mp.count(str1))	mp[str1] = u++;
			if(!mp.count(str2)) mp[str2] = u++;
			t1 = mp[str1];
			t2 = mp[str2];
			edge.push_back(Edge(t1,t2, inf, 0));
			edge.push_back(Edge(t2, t1, 0, 0));
			m = edge.size();
			G[t1].push_back(m-2);
			G[t2].push_back(m-1);
		}
		printf("%d\n", nct-ek());
		if(tt)
			printf("\n");
	}
	return 0;
}
			

猜你喜欢

转载自blog.csdn.net/WukongAKK/article/details/81134601