题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配。匹配有n个数,代表某个儿子和哪个女孩可以结婚。已知这些条件,要你找出每个儿子可以和哪些女孩结婚
思路:求强联通分量。同时练习一下输入输出外挂可以减少时间
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<vector> 9 using namespace std; 10 const int maxn=1e5+7; 11 const double eps=1e-8; 12 const double pi=acos(-1); 13 const int inf = 0x3f3f3f3f; 14 #define ll long long 15 #define clc(a,b) memset(a,b,sizeof(a)) 16 17 const int N=4005; 18 const int M=204000; 19 struct Edge { 20 int v,next; 21 } edge[M]; 22 23 int first[N],low[N],dfn[N],sta[M],belong[N],ans[N]; 24 bool instack[N]; 25 int g,cnt,top,scc; 26 27 void addedge(int u,int v) { 28 edge[g].v=v; 29 edge[g].next=first[u]; 30 first[u]=g++; 31 } 32 33 int min(int a,int b) { 34 return a<b?a:b; 35 } 36 37 void tarjan(int u) { 38 int i,v; 39 low[u]=dfn[u]=++cnt; 40 sta[++top]=u; 41 instack[u]=true; 42 for(i=first[u]; i!=-1; i=edge[i].next) { 43 v=edge[i].v; 44 if(!dfn[v]) { 45 tarjan(v); 46 low[u]=min(low[u],low[v]); 47 } else if(instack[v]) { 48 low[u]=min(low[u],dfn[v]); 49 } 50 } 51 if(low[u]==dfn[u]) { 52 scc++; 53 while(1) { 54 v=sta[top--]; 55 instack[v]=false; 56 belong[v]=scc; 57 if(u==v) 58 break; 59 } 60 } 61 } 62 63 int scan() { 64 int res=0,ch,flag=0; 65 if((ch=getchar())=='-') 66 flag=1; 67 else if(ch>='0'&&ch<='9') 68 res=ch-'0'; 69 while((ch=getchar())>='0'&&ch<='9') 70 res=res*10+ch-'0'; 71 return flag?-res:res; 72 } 73 74 void out(int a) { 75 if(a>9) 76 out(a/10); 77 putchar(a%10+'0'); 78 } 79 80 int main() { 81 int n,i,u,v,k; 82 while(scanf("%d",&n)!=EOF) { 83 g=cnt=top=scc=0; 84 clc(first,-1); 85 clc(dfn,0); 86 clc(instack,false); 87 for(i=1; i<=n; i++) { 88 k=scan(); 89 while(k--) { 90 v=scan(); 91 addedge(i,v+n); 92 } 93 } 94 for(i=1;i<=n;i++){ 95 v=scan(); 96 addedge(v+n,i); 97 } 98 for(i=1;i<=2*n;i++){ 99 if(!dfn[i]) 100 tarjan(i); 101 } 102 for(u=1;u<=n;u++){ 103 int countt=0; 104 for(i=first[u];i!=-1;i=edge[i].next){ 105 v=edge[i].v; 106 if(belong[u]==belong[v]) 107 ans[countt++]=v-n; 108 } 109 sort(ans,ans+countt); 110 out(countt); 111 for(i=0;i<countt;i++){ 112 putchar(' '); 113 out(ans[i]); 114 } 115 putchar(' '); 116 } 117 } 118 return 0; 119 }