您的位置:首页 > 其它

zoj 1157 || poj 1087 A Plug for UNIX

2011-02-27 15:53 369 查看
最大二分匹配,建图真繁琐!!!



读题读了半天。。。



大意是,一些设备需要固定型号的插座,有的插座可以通过另一种设备得到。



比如样例





4

A

B

C

D

5

laptop B

phone C

pager B

clock B

comb X

3

B X

X A

X D





有ABCD四种插座,其中comb的插头是X型号的,而A,D上有X型号的插孔,所以相当于,comb可以和A,D相连。



建图后,用floyd把所有点能连通的都连下,然后匈牙利算法即可。



当然不在已知插座里的插座肯定是不能用的。



有几个小崩溃的点,第二部分输入中,可以输入第一部分没有的插座。第三部分输入中,可以输入第一、第二部分都没有的插座,但是不能忽略他们,因为可能需要靠他们把出现在第一部分的插座给连起来 = =。。。这点纠结了很久,最后测了数据才测出来,悲剧!!!



第一部分和第二部分的名字是没有重复的。



P.S:poj输入格式和zoj不一样。。。



#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <algorithm>
#define MAX 520
using namespace std;
char ch[MAX][30];
int map[MAX][MAX];
char str[MAX][30];
char adp[30];
int used[MAX],mat[MAX];
int n,m,nn;
int Augement(int x)
{
	int i;
	for(i=m+1; i<=m+nn; i++)
		if( !used[i] && map[x][i] )
		{
			used[i] = 1;
			if( !mat[i] || Augement(mat[i]) )
			{
				mat[i] = x;
				return 1;
			}
		}
	return 0;
}
int Hungary()
{
	int i,sum = 0;
	memset(mat,0,sizeof(mat));
	for(i=1; i<=m; i++)
	{
		memset(used,0,sizeof(used));
		if( Augement(i) )
			sum++;
	}
	return sum;
}
int main()
{
	int ncases;
	int i,k,p,j;
	char a[30],b[30];
	scanf("%d",&ncases);
	while( ncases-- )
	{
		scanf("%d",&n);
		memset(map,0,sizeof(map));
		for(i=1; i<=n; i++)
			scanf("%s",ch[i]);
		nn = n;
		scanf("%d",&m);
		for(i=1; i<=m; i++)
		{
			scanf("%s %s",str[i],adp);
			int flag = 0;
			for(k=1; k<=n; k++)
				if( strcmp(adp,ch[k]) == 0 )
				{
					flag = 1;
					map[i][k+m] = 1;
					break;
				}
			if( flag == 0 )
			{
				n++;
				memcpy(ch
,adp,sizeof(adp));
				map[i][m+n] = 1;
			}	
		}
		scanf("%d",&p);
		while( p-- )
		{
			scanf("%s %s",a,b);
			int tmpb = -1,tmpa = -1;
			for(i=1; i<=n; i++)
			{
				if( tmpb != -1 && tmpa != -1 )
					break;
				if( strcmp(b,ch[i]) == 0 )
					tmpb = i;
				if( strcmp(a,ch[i]) == 0 )
					tmpa = i;
			}
			if( tmpb == -1 )
			{
				n++;
				memcpy(ch
,b,sizeof(b));
				tmpb = n;
			}
			if( tmpa == -1 )
			{
				n++;
				memcpy(ch
,a,sizeof(a));
				tmpa = n;
			}
			map[tmpa+m][tmpb+m] = 1;
		}			
		for(i=1; i<=m+n; i++)
			for(k=1; k<=m+n; k++)
				for(j=1; j<=m+n; j++)
					if( map[k][i] && map[i][j] && !map[k][j] )
						map[k][j] = 1;
		int ans = Hungary();
		printf("%d/n",m-ans);
		if( ncases )
			printf("/n");
	}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: