• Poj 1904 King's Quest 强连通分量


    题目链接:

    http://poj.org/problem?id=1904

    题意:

    有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可以取哪些公主,并且保证取了一个公主后,全局还是存在完美匹配。

    题解:

    1、建图:

    如果王子u对公主v心仪,则连一条边u->v。在样例给出的那组完美匹配中,如果王子u娶了公主v,连一条边v->u。

    2、求强连通分量:

    如果王子和自己心仪的公主属于同一个强连通分量,那么王子就可以娶这个公主。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<stack>
      5 #include<vector>
      6 #include<cstring>
      7 using namespace std;
      8 
      9 const int maxn=4444;
     10 
     11 int N;
     12 
     13 struct Edge{
     14     int v,ne;
     15     Edge(int v,int ne):v(v),ne(ne){}
     16     Edge(){}
     17 }egs[201010+maxn];
     18 
     19 int head[maxn],tot;
     20 
     21 void addEdge(int u,int v){
     22     egs[tot]=Edge(v,head[u]);
     23     head[u]=tot++;
     24 }
     25 
     26 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
     27 stack<int> S;
     28 
     29 int scan(){
     30     int ret=0,flag=0; char ch;
     31     if((ch=getchar())=='-') flag=1;
     32     else if(ch>='0'&&ch<='9') ret=ch-'0';
     33     while((ch=getchar())>='0'&&ch<='9') ret=ret*10+ch-'0';
     34     return flag?-ret:ret;
     35 }
     36 
     37 void out(int x){
     38     if(x>9) out(x/10);
     39     putchar(x%10+'0');
     40 }
     41 
     42 void dfs(int u){
     43     pre[u]=lowlink[u]=++dfs_clock;
     44     S.push(u);
     45     for(int i=head[u];i!=-1;i=egs[i].ne){
     46         Edge& e=egs[i];
     47         int v=e.v;
     48         if(!pre[v]){
     49             dfs(v);
     50             lowlink[u]=min(lowlink[u],lowlink[v]);
     51         }else if(!sccno[v]){
     52             lowlink[u]=min(lowlink[u],pre[v]);
     53         }
     54     } 
     55     if(lowlink[u]==pre[u]){
     56         scc_cnt++;
     57         for(;;){
     58             int x=S.top(); S.pop();
     59             sccno[x]=scc_cnt;
     60             if(x==u) break; 
     61         }
     62     }
     63 }
     64 
     65 void find_scc(int n){
     66     dfs_clock=scc_cnt=0;
     67     memset(sccno,0,sizeof(sccno));
     68     memset(pre,0,sizeof(pre));
     69     for(int i=0;i<n;i++){
     70         if(!pre[i]) dfs(i);
     71     }
     72 }
     73 
     74 void build(){
     75     int cnt,v;
     76     for(int i=0;i<N;i++){
     77         cnt=scan();
     78         while(cnt--){
     79             v=scan(); v--;    
     80             addEdge(i,v+N);
     81         }
     82     }
     83     for(int i=0;i<N;i++){
     84         v=scan(); v--;
     85         addEdge(v+N,i);
     86     }
     87 }
     88 
     89 void init(){
     90     memset(head,-1,sizeof(head));
     91     tot=0;
     92 }
     93 
     94 int ans[201010],t;
     95 
     96 int main(){
     97     while(scanf("%d",&N)==1&&N){
     98         init();
     99         build();
    100         find_scc(2*N);
    101         for(int i=0;i<N;i++){
    102             t=0;
    103             for(int j=head[i];j!=-1;j=egs[j].ne){                
    104                 Edge& e=egs[j];
    105                 int v=e.v;
    106                 if(sccno[i]==sccno[v]) ans[t++]=v;
    107             }
    108             sort(ans,ans+t);
    109             out(t);
    110             for(int i=0;i<t;i++){
    111                 putchar(' ');
    112                 out(ans[i]+1-N);
    113             }
    114             putchar('
    ');
    115         }
    116     }
    117     return 0;
    118 } 
  • 相关阅读:
    Ext JS 6学习文档-第5章-表格组件(grid)
    Ext JS 6学习文档-第4章-数据包
    Ext JS 6学习文档-第3章-基础组件
    Ext JS 6学习文档–第2章–核心概念
    Ext JS 6学习文档–第1章–ExtJS入门指南
    Console命令详解,让调试js代码变得更简单
    使用Node.js+Socket.IO搭建WebSocket实时应用
    node.js应用--转载
    Node.js 究竟是什么?
    Hello, Unity!
  • 原文地址:https://www.cnblogs.com/fenice/p/5509935.html
Copyright © 2020-2023  润新知