解题报告 之 SGU242 Student's Morning

解题报告 之 SGU242 Student‘s Morning

Description

One Monday morning after some very fun party N students woke up at the flat of one of them. Notice that it was a Monday morning and every student of that party needs to be in his university this day. But nobody wants to go to his university alone (there were
students from different universities). So, they decided to select from all universities only K of them to visit. Every selected university must be visited by at least two of the students. Every student has his own preference list of universities. It means,
if some university is in list of some student‘s preferred universities, this student can go to this university with some non-empty company of students. Notice, that some of students can stay at the flat and continue drinking "juices" and playing "games". For
example, student Shokman was to stay home (due to failed exam) with foreign student Chokman, who remained home because of runny nose.

In that problem there are no preferences between students, because if they have very fun party that already means that everyone of them prefers anybody from this company.

More formally, your task is, given numbers of students, selected universities and preference list of every student, to decide whether it is possible to visit all universities by at least two of students or no, and if it is possible you must output for each
university numbers of students, which have to go to it in one company. One student can‘t be in more than one company.

Input

First line of input file contains two numbers N and K (0<=K<=N<=200). Next N lines contain preference lists of each student. Every preference list is started by number of preferred universities followed by numbers of these universities.

Output

First line of output file must contain word "YES" (without quotes), if it possible to visit all universities, satisfying rules of that task or word "NO" (also without quotes) when it is impossible. In case of positive answer next K lines must contain lists
of students, who are going to corresponding university. First number in list of students must be a number of students in the list, followed by numbers of these students.

Sample test(s)

Input


4 2 1 1 2 1 2 1 2 2 1 2 3 2 2 1 2 2 1 2 2 1 2

Output


YES

2 1 2

2 3 4

NO

题目大意:好好一道水题你搞什么阅读理解! n个学生m个大学,每个学生有自己想去的大学,一个学生最多去一个大学(也可不去),每个大学至少要有两个人去,问是否是一种方案满足?如果有则输出任意一种满足的方案。

分析:有点像二分图匹配,然后用满流判断是否满足,再加上残余网络法输出方案。具体思路如下,超级源点与每个学生相连,负载为1,每个大学与超级汇点相连,负载为2。每个学生与要去的每所大学相连,负载都为1。然后跑最大流,如果满足max_flow==m*2,表示有解。此时扫描残余网络中与学生相连的每条边,如果不是与src相连的边且负载减小了(说明该学生去了该学校),则加入到对应大学的list中,最后输出list完事儿。另外此题内存稍小,所以必须控制好边数,大概是n*m多一点儿。

上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;

const int MAXN = 520;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;

struct Edge
{
	int from, to, cap, next, oricap;
};

Edge edge[MAXM];
int head[MAXN];
int stu[405][405];
int level[MAXN];
int src, des, cnt;

void addedge( int from, int to, int cap )
{
	edge[cnt].from = from;
	edge[cnt].to = to;
	edge[cnt].cap = cap;
	edge[cnt].oricap = cap;
	edge[cnt].next = head[from];
	head[from] = cnt++;

	swap( from, to );

	edge[cnt].from = from;
	edge[cnt].to = to;
	edge[cnt].cap = 0;
	edge[cnt].oricap = 0;
	edge[cnt].next = head[from];
	head[from] = cnt++;
}

int bfs( )
{
	memset( level, -1, sizeof level );
	queue<int> q;
	while (!q.empty( ))
		q.pop( );

	level[src] = 0;
	q.push( src );

	while (!q.empty( ))
	{
		int u = q.front( );
		q.pop( );

		for (int i = head[u]; i != -1; i = edge[i].next)
		{
			int v = edge[i].to;
			if (edge[i].cap > 0 && level[v] == -1)
			{
				level[v] = level[u] + 1;
				q.push( v );
			}
		}
	}
	return level[des] != -1;
}

int dfs( int u, int f )
{
	if (u == des)	return f;
	int tem;
	for (int i = head[u]; i != -1; i = edge[i].next)
	{
		int v = edge[i].to;
		if (edge[i].cap > 0 && level[v] == level[u] + 1)
		{
			tem = dfs( v, min( f, edge[i].cap ) );
			if (tem > 0)
			{
				edge[i].cap -= tem;
				edge[i ^ 1].cap += tem;
				return tem;
			}
		}
	}
	level[u] = -1;
	return 0;
}

int Dinic( )
{
	int ans = 0, tem;
	while (bfs( ))
	{
		while ((tem = dfs( src, INF )) > 0)
		{
			ans += tem;
		}
	}
	return ans;
}

int main( )
{
	int n, m;
	src = 0; des = 510;
	string str;
	while (cin >> n >> m)
	{
		memset( head, -1, sizeof head );
		cnt = 0;
		for (int i = 1; i <= n; i++)
		{
			addedge( src, i, 1 );
			int unum;
			cin >> unum;
			for (int j = 1; j <= unum; j++)
			{
				int u;
				cin >> u;
				addedge( i, u + 200, 1 );
			}
		}

		for (int i = 1; i <= m; i++)
		{
			addedge( i + 200, des, 2 );
			stu[i + 200][0] = 0;
		}
		if (Dinic( ) < m * 2)
		{
			cout << "NO" << endl;
			continue;
		}
		for (int i = 1; i <= n; i++)
		{
			for (int j = head[i]; j != -1; j = edge[j].next)
			{
				if (edge[j].to != src&&edge[j].oricap>edge[j].cap)
				{
					stu[edge[j].to][++stu[edge[j].to][0]] = i;
				}
			}
		}

		cout << "YES" << endl;
		for (int i = 1; i <= m; i++)
		{
			cout << stu[i + 200][0] << " ";
			for (int j = 1; j < stu[i + 200][0]; j++)
			{
				cout << stu[i + 200][j] << " ";
			}
			cout << stu[i + 200][stu[i + 200][0]] << endl;
		}
	}

	return 0;
}

好吧。。。祝愿信息安全大赛成功,虽然我是抱大腿的哈哈哈哈哈哈哈哈BJ4.。。

解题报告 之 SGU242 Student's Morning

时间: 2024-09-28 12:56:43

解题报告 之 SGU242 Student's Morning的相关文章

解题报告 之 POJ2769 Reduced ID Numbers

解题报告 之 POJ2769 Reduced ID Numbers Description T. Chur teaches various groups of students at university U. Every U-student has a unique Student Identification Number (SIN). A SIN s is an integer in the range 0 ≤ s ≤ MaxSIN with MaxSIN = 10 6-1. T. Chu

poj 2771 Guardian of Decency 解题报告

题目链接:http://poj.org/problem?id=2771 题目意思:有一个保守的老师要带他的学生来一次短途旅行,但是他又害怕有些人会变成情侣关系,于是就想出了一个方法: 1.身高差距  > 40cm 2.相同性别 3.喜欢的音乐种类  不同 4.有共同喜爱的 运动 只要满足其中这4个条件中的一个(当然越多越好啦),就可以将他们编为一组啦(一组两个人),求能被编为一组的最多组数. 这题实质上求的是二分图的最大独立集.  最大独立集 = 顶点数 - 最大匹配数 可以这样转化:两个人至少

sgu-242 Student&#39;s Morning

题目大意: 有N个人,K个大学,每个人有Gi个心仪的学校,为集合Si,然后然后这N个人可以去任意一个且仅一个他心仪的学校,问是否可以使得K个学校每个学校都有不小于2个人去.如果没有,输出"NO",否则输出"YES",然后接下来K行,每行一个数,表示去第i个学校的人有几个,接下来输出那几个人去哪个学校.PS:有的人可以不去学校,只要满足每个学校有2个及以上的人去就行了,不要求N个人每个人都去上学,比如可以在家浪...... 解题思路: 首先这道题目显然可以用有上下确界

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

hdu 1541 Stars 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有比它低层(或者同层)的或者在它左手边的星星数决定.计算出每个等级(0 ~ n-1)的星星各有多少颗. 我只能说,题目换了一下就不会变通了,泪~~~~ 星星的分布是不是很像树状数组呢~~~没错,就是树状数组题来滴! 按照题目输入,当前星星与后面的星星没有关系.所以只要把 x 之前的横坐标加起来就可以了

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

[noip2011]铺地毯(carpet)解题报告

最近在写noip2011的题,备战noip,先给自己加个油! 下面是noip2011的试题和自己的解题报告,希望对大家有帮助,题目1如下 1.铺地毯(carpet.cpp/c/pas) [问题描述]为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有n 张地毯,编号从1 到n.现在将这些地毯按照编号从小到大的顺序平行于坐标轴先后铺设,后铺的地毯覆盖在前面已经铺好的地毯之上.地毯铺设完成后,组织者想知道覆盖地面某个点的最上面的那张地毯的

ACdream 1203 - KIDx&#39;s Triangle(解题报告)

KIDx's Triangle Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description One day, KIDx solved a math problem for middle students in seconds! And than he created this problem. N