hdu2444 染色法+二分图匹配

有n个关系,他们之间某些人相互认识。这样的人有m对。
你需要把人分成2组,使得每组人内部之间是相互不认识的。
如果可以,就可以安排他们住宿了。安排住宿时,住在一个房间的两个人应该相互认识。
最多的能有多少个房间住宿的两个相互认识。

首先题目是要问能不能分成两组,每组人之间互相不认识,每个人只与对面那部分的人认识。这个就是要判断是不是能构成一个二分图的样子。
判断二分图我们使用染色法,就是规定一个点的颜色,然后与其相连的点的颜色是不同的,如果遇到了无法满足的情况,(比如之前颜色是1 , 但是到现在你又要这个点颜色是2就无法满足)。判断是二分图后,直接二分图匹配模板就可以了。还有个小问题就是,我们二分图匹配出来的数目要除以2,因为他是比如1和2匹配,2和1匹配算作了两种,所以答案去除以2就好了。
有任何问题尽管留言,我会尽量回复。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<time.h>
#include<cmath>
using namespace std;
const long long max_ = 1e3 + 7;
int tu[max_][max_];
int read()
{
	int s = 0, f = 1;
	char ch = getchar();
	while (ch<'0' || ch>'9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0'&&ch <= '9') {
		s = s * 10 + ch - '0';
		ch = getchar();
	}
	return s * f;
}

int n, m, e, vis[max_], match[max_];
int dfs(int now) {
	for (int i = 1; i <= n; i++) {
		if (tu[now][i] && !vis[i]) {
			vis[i] = 1;
			if (match[i] == 0 || dfs(match[i])) {
				match[i] = now;
				return 1;
			}
		}
	}
	return 0;
}
int color[max_];
int bfs(int now) {
	queue<int>node;
	node.push(now);
	while (!node.empty()) {
		int tou = node.front();
		node.pop();
		for (int i = 1; i <= n; i++) {
			if (tu[tou][i] == 1) {
				if (color[i] == 0) {
					color[i] = (color[tou] == 1 ? 2 : 1);
					node.push(i);
				}
				else {
					if (color[i] == color[tou])return 0;
				}
			}
		}
	}
	return 1;
}
void qing() {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			tu[i][j] = 0;
		}
		match[i] = 0;
		color[i] = 0;
	}
}
int main() {
	while (scanf_s("%d%d", &n,&m)!=EOF) {
		qing();
    while (m--) {
		int a = read(), b = read();
		tu[a][b] = 1;
		tu[b][a] = 1;
	}
	int sum = 0;
	color[1] = 1;
	if (!bfs(1)||n==1) { cout << "No" << endl; continue; }
	for (int i = 1; i <= n; i++) {
		memset(vis, 0, sizeof(vis));
		sum += dfs(i);
	}
	cout << sum/2 << endl;	
	}
	
	return 0;
}
全部评论

相关推荐

零OFFER战士:另一个版本查看图片
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-08 10:39
一个证都没&nbsp;我能填什么
程序员小白条:别人有,你为什么没有,还是这个道理,社会就是比较,竞争,淘汰,你要安逸,那么就要做好淘汰的准备
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务