POJ 1904 King's Quest 强联通分量+输入输出外挂

题意:国王有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('\n');
116          }
117     }
118     return 0;
119 }
View Code

 

posted @ 2016-03-10 11:05  yyblues  阅读(231)  评论(0编辑  收藏  举报