zoukankan      html  css  js  c++  java
  • POJ

    题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子。但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶。

    分析:设王子为x部,妹子为y部,假设有匹配xi与yi和xj和yj,当xi中意yj且xj中意yi时。那么xi,xj改变对象不会影响最大匹配数。可以将寻找新的伴侣与匈牙利算法中寻找增广路的过程联想在一起。如果在这几对人中能找到一条完整地交错轨,那么就可以对Y部进行任意选择。

    所以本题转化为球每个强连通分量中的点。

    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    #include<stack>
    #include<algorithm>
    #include<vector>
    using namespace std;
    typedef long long LL;
    const int maxn =4e3+5,maxm = 3e5+5;
    const int INF =0x3f3f3f3f;
    struct Edge{int to,next;}edges[maxm];
    int head[maxn],tot;
    stack<int> S;
    int pre[maxn],low[maxn],sccno[maxn],dfn,scc_cnt;
    int sccnum[maxn];
    void init(int N)
    {
        tot=dfn=scc_cnt=0;
        memset(pre,0,sizeof(pre));
        memset(sccno,0,sizeof(sccno));
        memset(head,-1,sizeof(head));
    }
    
    void AddEdge(int u,int v)   {
        edges[tot] = (Edge){v,head[u]};
        head[u] = tot++;
    }
    void Tarjan(int u)
    {
        int v;
        pre[u]=low[u]=++dfn;
        S.push(u);
        for(int i=head[u];~i;i=edges[i].next){
            v= edges[i].to;
            if(!pre[v]){
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(!sccno[v]){
                low[u]=min(low[u],pre[v]);
            }
        }
        if(pre[u]==low[u]){
            int x;
            ++scc_cnt;
            for(;;){
                x = S.top();S.pop();
                sccno[x]=scc_cnt;
                if(x==u)break;
            }
        }    
    }
    int Scan()     //输入外挂
    {
        int res=0,ch,flag=0;
        if((ch=getchar())=='-')
            flag=1;
        else if(ch>='0'&&ch<='9')
            res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
            res=res*10+ch-'0';
        return flag?-res:res;
    }
    void Out(int a)    //输出外挂
    {
        if(a>9)
            Out(a/10);
        putchar(a%10+'0');
    }
    
    int res[maxn];
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int N,u,v,k,tmp;
        while(scanf("%d",&N)==1){
            init(N*2);
            for(int i=1;i<=N;++i){
                k = Scan();
                while(k--){
                    v = Scan();
                    AddEdge(i,v+N);
                }
            }
            for(int i=1;i<=N;++i){
                u = Scan();
                AddEdge(u+N,i);
            }
            for(int i=1;i<=2*N;++i){
                if(!pre[i])
                    Tarjan(i);
            }
            for(int u=1;u<=N;++u){
                int cnt=0;
                for(int i=head[u];~i;i=edges[i].next){
                    int v = edges[i].to;
                    if(sccno[u]==sccno[v]){
                        res[cnt++] = v-N;
                    }
                }
                sort(res,res+cnt);
                Out(cnt);
                for(int i=0;i<cnt;++i){
                    putchar(' ');
                    Out(res[i]);
                }
                putchar('
    ');
            }
        }
        return 0;
    }
    为了更好的明天
  • 相关阅读:
    微信小程序支付接口之Django后台
    wx.request 请求与django
    ubuntu16.04 安装使用meld及问题
    微信小程序上传单张或多张图片
    ip地址掩码和位数对应关系表、子网掩码、网络地址、主机地址-yellowcong
    公网IP地址就一定是A类地址和B类地址吗?那C类地址就一定是私有地址吗?
    太厉害了,终于有人能把TCP/IP协议讲的明明白白了!
    linux/shell/bash 自动输入密码或文本
    shell case例子
    spring 配置Value常量(不支持到static上)
  • 原文地址:https://www.cnblogs.com/xiuwenli/p/9486705.html
Copyright © 2011-2022 走看看