zoukankan      html  css  js  c++  java
  • 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('
    ');
    116          }
    117     }
    118     return 0;
    119 }
    View Code
  • 相关阅读:
    《ACM国际大学生程序设计竞赛题解I》——6.8
    数据结构篇
    从SG函数浅谈解决博弈问题的通法
    动态规划的泛式解题思路
    bzoj1057: [ZJOI2007]棋盘制作
    bzoj3884: 上帝与集合的正确用法
    bzoj1564: [NOI2009]二叉查找树
    bzoj4347: [POI2016]Nim z utrudnieniem
    bzoj1131: [POI2008]Sta
    bzoj1566: [NOI2009]管道取珠
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5261049.html
Copyright © 2011-2022 走看看