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;
}
静渊以有谋,疏通而知事。
浙公网安备 33010602011771号