POJ1904 King's Quest

King's Quest

国王有n个儿子,每个儿子喜欢ki个女孩,国王想让王子与他喜欢的人结婚,就让巫师做一个列表出来,但是国王想知道王子能和哪些女孩结婚,并且不影响其他王子也能与自己喜欢的女孩在一起;

题解

求的就是做大匹配可行边,并且这还是完美匹配,所以可以直接连边跑SCC。

值得一提的是,我在POJ上用%llu输出就WA了,调了一个小时。Z前辈告诉我POJ上vector的size类型是unsigned

#include<iostream>
#include<vector>
#include<algorithm>
#include<cassert>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=4e3+1;
int n,b[N],c[N],cnt;
vector<int> a[N],e[N],ans[N];
int dfn[N],low[N],num;
int st[N],top,ins[N];

void tarjan(int x){
	dfn[x]=low[x]=++num;
	st[++top]=x,ins[x]=1;
	for(unsigned i=0;i<e[x].size();++i){
		int y=e[x][i];
		if(!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(ins[y]) low[x]=min(low[x],dfn[y]);
	}
	if(low[x]==dfn[x]){
		++cnt;
		int y;
		do{
			y=st[top--],ins[y]=0;
			c[y]=cnt;
		}while(y!=x);
	}
}
int main(){
	read(n);
	for(int i=1;i<=n;++i){
		int k=read<int>();
		while(k--) a[i].push_back(read<int>());
	}
	for(int i=1;i<=n;++i) read(b[i]);
	for(int x=1;x<=n;++x)
		for(unsigned i=0;i<a[x].size();++i){
			int y=a[x][i];
			if(y==b[x]) e[y+n].push_back(x);
			else e[x].push_back(y+n);
		}
	for(int i=1;i<=n<<1;++i)
		if(!dfn[i]) tarjan(i);
	for(int x=1;x<=n;++x){
		for(unsigned i=0;i<a[x].size();++i){
			int y=a[x][i];
			if(y==b[x]||c[x]==c[y+n]) ans[x].push_back(y);
		}
		sort(ans[x].begin(),ans[x].end()); // edit 1: ascending order
//		printf("%llu",ans[x].size());
		printf("%d",(int)ans[x].size()); // edit 2: thanks to POJ
		for(unsigned i=0;i<ans[x].size();++i)
			printf(" %d",ans[x][i]);
		puts("");
	}
	return 0;
}

posted on 2019-06-19 16:03  autoint  阅读(102)  评论(0)    收藏  举报

导航