HDU 5943 - Kingdom of Obsession(二分图匹配)


题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5943

【题意】

给定n,s,现在让1-n和s+1,s+2...s+n这两堆数匹配,如果(s+i)%j==0那么s+i就可以和j构成一个匹配,求是否能让所有的n个

数字都构成匹配。(n, s <= 1e9)


【思路】

首先,如果1-n这n个数中出现了素数那么就一定无法让所有数字都匹配,而2e9以内的数字里面,最大的素数间隔不超过300,

这是一个很关键的结论,所以当n很大时直接输出"No"即可。当n比较小时,变成了一个二分匹配的问题,用匈牙利算法实现。

判断是否能够全部匹配即可。

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

const int maxn = 1050;

int n, s;
int used[maxn];
int link[maxn];
int g[maxn][maxn];

bool find(int x) {
	for (int i = 1; i <= n; ++i) {
		if (!used[i] && g[x][i] == 1) {
			used[i] = 1;
			if (link[i] == 0 || find(link[i])) {
				link[i] = x;
				return 1;
			}
		}
	}
	return 0;
}

int main() {
	int t;
	scanf("%d", &t);
	for (int kase = 1; kase <= t; ++kase) {
		scanf("%d%d", &n, &s);
		printf("Case #%d: ", kase);
		if (n > s) swap(n, s); 
		if (n > 1000) {
			printf("No\n");
			continue;
		}
		
		memset(g, 0, sizeof(g));
		for (int i = 1; i <= n; ++i) {
			int tmp = s + i;
			for (int j = 1; j <= n; ++j)
				if (tmp % j == 0) g[i][j] = 1;
		}
		
		memset(link, 0, sizeof(link));
		int ans = 0;
		for (int i = 1; i <= n; ++i) {
			memset(used, 0, sizeof(used));
			if (find(i)) ++ans;
		}
		printf("%s\n", ans == n ? "Yes" : "No");
	}
	return 0;
}


posted @ 2018-01-07 22:05  不想吃WA的咸鱼  阅读(73)  评论(0编辑  收藏  举报