ZOJ1157-A Plug for UNIX

#include <iostream>
using namespace std;

string names[400];
int numName;
int numReceps;
int numAdapts;
int matchPlug[100];
int matchRecep[100];
bool canUse[100];

struct plug {
	int recep;
	bool list[400];	
} plugs[100];

struct adapter {
	int recep, plug;
} adapts[100];

int findName(string name)
{
	for(int i=0; i<numName; i++)
		if (name == names[i]) return i;
	names[numName++] = name;
	return numName-1;
}

void useAdapter(int i)
{
	plugs[i].list[plugs[i].recep] = true;
	bool flag;
	do {
		flag = false;
		for(int j=0; j<numAdapts; j++) 
		{
			if (plugs[i].list[adapts[j].recep] && 
				!plugs[i].list[adapts[j].plug]) 
			{
				flag = true;
				plugs[i].list[adapts[j].plug] = true;
			}
		}
	} while (flag);
}

bool backtrack(int node)
{
	for(int j=0; j<numReceps; j++) 
	{
		if (plugs[node].list[j] && canUse[j]) 
		{
			if (matchRecep[j] == -1) 
			{
				matchPlug[node] = j;
				matchRecep[j] = node;
				return true;
			}
			else 
			{
				int save = matchRecep[j];
				matchRecep[j] = node;
				matchPlug[save] = -1;
				matchPlug[node] = j;
				canUse[j] = false;
				if (backtrack(save))
					return true;
				canUse[j] = true;
				matchPlug[node] = -1;
				matchPlug[save] = j;
				matchRecep[j] = save;
			}
		}
	}
	return false;
}

int main() 
{
	int numPlugs;
	string name;
	int N;
	scanf("%d", &N);
	while (N--) 
	{
		cin >> numReceps;
		for(int i=0; i<numReceps; i++) 
			cin >> names[i];
		numName = numReceps;
		
		cin >> numPlugs;
		for(int i=0; i<numPlugs; i++) 
		{
			cin >> name >> name;
			plugs[i].recep=findName(name);
			memset(plugs[i].list, false, sizeof(plugs[i].list));
		}
		
		cin >> numAdapts;
		for(int i=0; i<numAdapts; i++) 
		{
			cin >> name;
			adapts[i].recep = findName(name);
			cin >> name;
			adapts[i].plug = findName(name);
		}
		
		for(int i=0; i<numPlugs; i++)
			useAdapter(i);
		memset(matchPlug, 0xff, sizeof(matchPlug));
		memset(matchRecep, 0xff, sizeof(matchRecep));
		
		int i=0;
		while(i < numPlugs)
		{
			for(int j=0; j<numReceps; j++)
				canUse[j] = true;
			if (matchPlug[i] == -1 && backtrack(i)) i = 0;
			else  i++;
		}
		
		int min = 0;
		for(int i=0; i<numPlugs; i++)
			if (matchPlug[i] == -1) min++;
		cout << min << endl;
		if (N) printf("\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值