POJ1081--You Who?

You Who?
Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 702Accepted: 249
Description
 
On the first day of first grade at Friendly Elementrary School, it is customary for each student to spend one minute talking to every classmate that he or she does not already know. When student Bob sees an unfamilar face, he says ``You who?'' A typical response is ``Me Charlie, you who?'' Then Bob says, ``Me Bob!'' and they talk for a minute. It's very cute. Then, after a minute, they part and each looks for another stranger to greet. This takes time. In class of twenty-nine or thirty mutual strangers, it takes 29 minutes; time that, according to teachers, could be better spent learning the alphabet. Of course, it is rare to have a first grade class where nobody knows anyone else; there are neighbors and playmates who already know each other, so they don't have to go through the get-to-know-you minutes with each other. 
The two first grade teachers have requested that, to save time, students be allocated to their two classes so that the difference in the sizes of the classes is at most one, and the time it takes to complete these introductions is as small as possible. There are no more than 60 students in the incoming first grade class. 
 
How can the assignment of students to classes be made? Your job is to write the software that answers the question. 
 
Input
 
The school records include information about these student friendships, represented as lists of numbers. If there are 29 students, then they are represented by the numbers 1 to 29. The record for a single student includes, first, his/her student identification number (1 to 29, in this example), then the number of his/her acquaintances, then a list of them in no particular order. So, for example, this record 
17 4 5 2 14 22 
 
indicates that student 17 knows 4 students: 5, 2, and so on. The records for all the students in the incoming class are represented as the list of numbers that results from concatenating all the student records together. Spaces and line breaks are irrelevent in this format. Thus, this 
 
1 1 2 2 1 1 
 
is a whole database, indicating that there are only two students in the incoming class, and they know each other; and this 
 
1 2 3 4 
2 2 3 4 
3 2 1 2 
4 2 1 2 
 
indicates that 1 doesn't know 2, and 3 doesn't know 4, but all other pairs know each other. 
 
The database has been checked for consistency, so that if A knows B, then B knows A. 
Output
 
Your output should begin with a number that tells how long it will take to complete the introductions in the best possible legal class assignment. For the simple two student problem above, the only legal answer is 
 
0
Sample Input
 
1 2 3 4 
2 2 3 4 
3 2 1 2 
4 2 1 2 
Sample Output
 
0
Hint
 

To make this problem more tractable, the following changes are being made. There will be exactly two classes. There will be no more that 30 students. The students will be divided as evenly as possible between the classes. The loneliness of a student is the number of students in his class whom he does not know. You are to arrange the classes to minimize the loneliness of the loneliest student. for the sample data ,you can arrange 1 and 3 to the first class,and 2 and 4 to the second class,then they need no time to know each other.


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

ifstream fin("C:\\data36.in");
ofstream fout("C:\\data37.out");

int partner[31][31];
int temp1[15],temp2[15];
int N;
int minmaxsolonum;

//找出分组中互相不认识的人的对数
int findSoloNum(int* arr,int num)
{
	int cnt=0;
	for(int i=0;i<num-1;++i)
	{
		for(int j=i+1;j<num;++j)
		{
			if(!partner[arr[i]][arr[j]])
				++cnt;
		}
	}
	return cnt;
}


void solution(int index,int num1,int num2)
{
	//只是因为两组的人数只差不能大于一,所以设一组有ceil(N/2)个人,二组有floor(N/2)个人,但限定了两组的人数之后,在总人数为偶数的时候,会导致重复遍历。但因为总人数不超过30,就算重复遍历也没什么关系
	if(num1==ceil(N/2)&&num2==floor(N/2))
	{
		int solonum1=findSoloNum(temp1,num1);
		int solonum2=findSoloNum(temp2,num2);
		//找出两组分组中最大的互不认识的人的对数,并和保存值minmaxsolonum相比较,并把较小值赋给minmaxsolonum;
		int maxsolonum=solonum1>solonum2?solonum1:solonum2;
		if(minmaxsolonum>maxsolonum)
		{
			minmaxsolonum=maxsolonum;
		}
		return;
	}
	else if(num1>ceil(N/2)||num2>floor(N/2))
	{
		return;
	}
	//这是把第index个人划给一组,找出把第index个人划给一组时最小的minmaxsolonum;
	temp1[num1]=index;
	solution(index+1,num1+1,num2);
	//然后把第index个人划给二组,找出吧第index个人划给二组时最小的minmaxsolonum;
	temp2[num2]=index;
	solution(index+1,num1,num2+1);
	//考虑完上面两种情况,所有的分组都已经遍历了,此时的minmaxsolonum值就是最小的minmaxsolonum,可以输出了
}

int main()
{
	int index,cnt,part;
	N=0;
	minmaxsolonum=1000;
	//初始化图
	memset(partner,0,sizeof(partner));
	while(fin>>index)
	{
		fin>>cnt;
		++N;
		for(int i=0;i<cnt;++i)
		{
			fin>>part;
			partner[index][part]=1;
		}
	}
	solution(1,0,0);
	cout<<minmaxsolonum<<endl;
	system("pause");
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值