POJ 2771 Guardian of Decency (最大独立集Hungary)

题意:老师想带他的学生们出去旅行,但是不想他们之间发生恋爱。也就是说,任意两个可能发生恋爱的人不能同时都带去。要求能带去旅行的最大人数。老师认为满足下列情况的人之间不会发生恋爱。
1.Their height differs by more than 40 cm.
2.They are of the same sex. 
3.Their preferred music style is different. 
4.Their favourite sport is the same (they are likely to be fans of different teams and that would result in fighting). 
题解:通过Trie树来给3,4两个条中的字符串编号。建图是关键。

#include <cmath>
#include <iostream>
using namespace std;

#define N 510
bool vis[N];
int bond[N][N], match[N];
int cnt, mark, n;

struct Student
{
	int h, m, s;
	char sex;
} stud[N];

struct Tree  
{  
    int key;  
    Tree *next[30];  
} node[N*2];  


int Insert ( char* word, Tree *location )  
{  
    int i = 0, id;  
    while ( word[i] )  
    {  
		if ( word[i] != '-' )
            id = word[i] - 'a';
		else id = 29;
        if ( location->next[id] == NULL )  
            location->next[id] = &node[++cnt];  
        location = location->next[id];  
        ++i;  
    }  
    if ( location->key == 0 )  
        location->key = ++mark;  //编号
    return location->key;  
}  

bool find_path ( int u )
{
	for ( int i = 1; i <= bond[u][0]; i++ )
	{
		int v = bond[u][i];
		if ( ! vis[v] )
		{
			vis[v] = 1;
			if ( !match[v] || find_path(match[v]) )
			{
				match[v] = u;
				return true;
			}
		}
	}
	return false;
}

int Hungary ()
{
	int ans = 0;
	memset(match,0,sizeof(match));
	for ( int i = 1; i <= n; i++ )
	{
		memset(vis,0,sizeof(vis));
		if ( find_path(i) ) ans++;
	}
	return ans;
}

bool check ( int a, int b )
{
	if ( abs(stud[a].h-stud[b].h) > 40 ) return false;
	if ( stud[a].sex == stud[b].sex ) return false;
	if ( stud[a].m != stud[b].m ) return false;
	if ( stud[a].s == stud[b].s ) return false;
	return true;
}

int main()
{
	char sex;
	char m[110], s[110];
	int t, h, i, j;

	scanf("%d",&t);
	while ( t-- )
	{
		mark = 0;
		cnt = 2;
		memset(bond,0,sizeof(bond));
		memset(node,NULL,sizeof(node));
		memset(stud,0,sizeof(stud));

		scanf("%d",&n);

		for ( i = 1; i <= n; i++ )
		{
			scanf("%d %c %s %s",&h,&sex,&m,&s);
			stud[i].h = h;
			stud[i].sex = sex;
			stud[i].m = Insert(m,&node[0]); // node[0]做为music的根节点
			stud[i].s = Insert(s,&node[1]); // node[1]作为sport的根节点
		}

		for ( i = 1; i <= n; i++ )
		{
			for ( j = 1; j <= n; j++ )
				if ( check ( i, j ) )
				{
					bond[i][0]++;
					bond[i][bond[i][0]] = j;
				}
		}
		printf("%d\n",n-Hungary()/2);
	}
	return 0;
}

			




你可能感兴趣的:(POJ 2771 Guardian of Decency (最大独立集Hungary))