题意:不说题意了,直接说它让干什么把,我们要找每个王子可以娶的女人,并且他娶了其中一个剩下的王子依然可以找到老婆,也就是固定一条边后,剩下的关系还是可以构成一个完备二分图,然后每个王子能娶的公主从小到大输出
思路:这种题没做过,看了看网上的题解,是要找强联通分量,那么可以肯定的是如果id号王子在强联通分量里,那么这里面的所有公主都满足条件,因为图是王子连公主,公主连王子的,我既然在一个联通分量里说明相互可达,那么也就是我这个王子可以到达所有的在这个联通分量的公主,而最后给的可以成功的分配方案是告诉你这样分配可以的嘛,那么将公主连向王子,跑强联通分量,分量里的王子可以到达所有这个分量里的公主,保存输出即可
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=4010;
vector<int> G[maxn];
vector<int> rG[maxn];
vector<int> vs;
bool used[maxn];
int cmp[maxn],V;
void add_edge(int from,int to){
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v){
used[v]=1;
for(int i=0;i<G[v].size();i++){
if(!used[G[v][i]]) dfs(G[v][i]);
}
vs.push_back(v);
}
void rdfs(int v,int k){
used[v]=1;
cmp[v]=k;
for(int i=0;i<rG[v].size();i++){
if(!used[rG[v][i]]) rdfs(rG[v][i],k);
}
}
int scc(){
memset(used,0,sizeof(used));
vs.clear();
for(int v=0;v<V;v++) if(!used[v]) dfs(v);
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1;i>=0;i--){
if(!used[vs[i]]) rdfs(vs[i],k++);
}
return k;
}
int num[maxn];
int main(){
int a,b,c,n;
while(scanf("%d",&n)!=-1){
for(int i=0;i<maxn;i++){
G[i].clear();
rG[i].clear();
}
vs.clear();
for(int i=1;i<=n;i++){
scanf("%d",&a);
while(a--){
scanf("%d",&b);
add_edge(i,b+n);
}
}
for(int i=1;i<=n;i++){
scanf("%d",&a);
add_edge(a+n,i);
}
V=2*n;
int ans=scc();
for(int i=1;i<=n;i++){
int sum=0;
for(int j=0;j<G[i].size();j++){
int t=G[i][j];
if(cmp[i]==cmp[t]){
num[sum++]=t;
}
}
sort(num,num+sum);
if(sum==0) printf("%d\n",sum);
else printf("%d ",sum);
for(int i=0;i<sum;i++){
if(i==sum-1) printf("%d\n",num[i]-n);
else printf("%d ",num[i]-n);
}
}
}
return 0;
}