Codeforces 1009G Allowed Letters FMT,二分图,二分图匹配,霍尔定理

原文链接https://www.cnblogs.com/zhouzhendong/p/CF1009G.html

题目传送门 - CF1009G

题意

  给定一个长度为 $n$ 的字符串 $s$ 。并给定 $m$ 条限制,第 $i$ 条限制声明了第 $i$ 个位置的字符可以取的值。如果没有声明表示可以任意取值。

  求一个字符串 $s$ 的排列,在满足 $m$ 条限制的同时,使得字典序最小。如果不存在满足限制条件的字符串,则输出 $-1$。

  $n,m\leq 10^5$,字符集 $ = {‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘}$

题解

  我们先考虑如何判定是否有解。

  统计一下原字符串中每一个字母的出现次数。容易建出一个二分图,左侧的 $n$ 个节点为字符串的每一个位置,右侧的 $n$ 个节点为 $n$ 个字母,这 $n$ 个字母中每种字符的出现次数等于原字符串中对应字符的出现次数;对于左侧的每一个点,即字符串的每一个位置,向它所能填的字母连上边(补充一下:这样做,右侧相同字母节点其实是等价的)。那么,只需要求出最大匹配数,就可以知道最多有多少个位置可以放正确的字母。

  然而,我们是否可以得到一种较快的判定是否有完美匹配的做法呢?显然有啊。

  霍尔定理:设一个二分图 G 中的两部分顶点组成的集合分别为 X, Y ,则 G 中有一组无公共点的边,一端恰好为组成X的点的充分必要条件是:X中的任意k个点至少与Y中的k个点相邻。

  根据霍尔定理,得到:

  命题1 :一个满足 |X| = |Y| 的二分图,存在完美匹配的充分必要条件是:在 X 中任选 k 个点,至少与 y 中 k 个点相邻;在 Y 中任选 k 个点,至少与 x 中 k 个点相邻。

  回到原图。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int read(){
	int x=0;
	char ch=getchar();
	while (!isdigit(ch))
		ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+ch-48,ch=getchar();
	return x;
}
char s[N];
int n,v[N],suf[N][64],tot[64],sum[64],Log[64];
void getv(){
	int m=read();
	memset(v,0,sizeof v);
	while (m--){
		int id=read();
		char s[10];
		scanf("%s",s+1);
		int len=strlen(s+1);
		for (int i=1;i<=len;i++)
			v[id]|=1<<(s[i]-‘a‘);
	}
	for (int i=1;i<=n;i++)
		if (v[i]==0)
			v[i]=63;
}
bool check(int p){
	sum[0]=0;
	for (int i=1;i<64;i++){
		sum[i]=sum[i^(i&-i)]+tot[i&-i];
		if (sum[i]<suf[p][i])
			return 0;
	}
	return 1;
}
int main(){
	Log[1]=0;
	for (int i=2;i<64;i++)
		Log[i]=Log[i>>1]+1;
	gets(s+1);
	n=strlen(s+1);
	getv();
	memset(tot,0,sizeof tot);
	for (int i=1;i<=n;i++)
		tot[1<<(s[i]-‘a‘)]++;
	memset(suf,0,sizeof suf);
	for (int i=n;i>=1;i--){
		for (int j=0;j<64;j++)
			suf[i][j]=suf[i+1][j];
		suf[i][v[i]]++;
	}
	for (int id=1;id<=n;id++)
		for (int i=1;i<64;i<<=1)
			for (int j=0;j<64;j++)
				if (j&i)
					suf[id][j]+=suf[id][j^i];
	if (!check(1)){
		printf("Impossible");
		return 0;
	}
	for (int i=1;i<=n;i++)
		for (int j=v[i],k=j&-j;j;j^=k,k=j&-j){
			tot[k]--;
			if (check(i+1)){
				putchar(‘a‘+Log[k]);
				break;
			}
			tot[k]++;
		}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/CF1009G.html

时间: 2024-11-07 09:13:52

Codeforces 1009G Allowed Letters FMT,二分图,二分图匹配,霍尔定理的相关文章

Codeforces 1009G Allowed Letters 最大流转最小割 sosdp

Allowed Letters 最直观的想法是贪心取, 然后网络流取check可不可行, 然后T了. 想到最大流可以等于最小割, 那么我们状压枚举字符代表的6个点连向汇点是否断掉, 然后再枚举64个本质不同的位置, 是否需要切段原点联想它的边, 复杂度电磁check复杂度64 * 64 用sosdp能优化到64 * 6 #include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned

Jamie&#39;s Contact Groups(二分图多重匹配+二分)(网络流)

Jamie's Contact Groups Time Limit:7000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2289 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list

POJ 2289--Jamie&#39;s Contact Groups【二分图多重匹配问题 &amp;&amp;二分查找最大值的最小化 &amp;&amp; 最大流】

Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 6902   Accepted: 2261 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list in her cell phone. The con

二分图多重匹配poj2289

Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 6511   Accepted: 2087 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long contact list in her cell phone. The con

POJ2289 Jamie&#39;s Contact Groups —— 二分图多重匹配/最大流 + 二分

题目链接:https://vjudge.net/problem/POJ-2289 Jamie's Contact Groups Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 8147   Accepted: 2736 Description Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very lon

HDU 1669 二分图多重匹配+二分

Jamie's Contact Groups Time Limit: 15000/7000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 747    Accepted Submission(s): 303 Problem Description Jamie is a very popular girl and has quite a lot of friends, so she

POJ2289:Jamie&#39;s Contact Groups(二分+二分图多重匹配)

Jamie's Contact Groups Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) 题目链接:http://poj.org/problem?id=2289 Description: Jamie is a very popular girl and has quite a lot of friends, so she always keeps a very long

hdu2255 奔小康赚大钱 二分图最佳匹配--KM算法

传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加