zoukankan      html  css  js  c++  java
  • POJ 1904 King's Quest 强连通分量+二分图增广判定

    http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html

    这位神说的很好

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <vector>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <utility>
    using namespace std;
    typedef long long LL;
    const int N=4e3+5;
    const int INF=0x3f3f3f3f;
    struct Edge
    {
        int v,next;
    } edge[N*N];
    int head[N],tot,n;
    void add(int u,int v)
    {
        edge[tot].v=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    stack<int>s;
    bool instack[N],mp[N/2+5][N/2+5];
    int dfn[N],low[N],clk,cnt,bel[N];
    void targin(int u)
    {
        dfn[u]=low[u]=++clk;
        instack[u]=true;
        s.push(u);
        for(int i=head[u]; ~i; i=edge[i].next)
        {
            int v=edge[i].v;
            if(!dfn[v])
            {
                targin(v);
                low[u]=min(low[u],low[v]);
            }
            else if(instack[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u])
        {
            ++cnt;
            int k;
            do
            {
                k=s.top();
                s.pop();
                instack[k]=false;
                bel[k]=cnt;
            }
            while(k!=u);
        }
    }
    vector<int>g;
    int main()
    {
        scanf("%d",&n);
        memset(head,-1,sizeof(head));
        for(int i=1; i<=n; ++i)
        {
            int k;
            scanf("%d",&k);
            for(int j=0; j<k; ++j)
            {
                int v;
                scanf("%d",&v);
                mp[i][v]=true;
                add(i,v+n);
            }
        }
        for(int i=1; i<=n; ++i)
        {
            int u;
            scanf("%d",&u);
            add(u+n,i);
        }
        for(int i=1; i<=n; ++i)
            if(!dfn[i])targin(i);
        for(int i=1; i<=n; ++i)
        {
            g.clear();
            int k1=bel[i],k2;
            for(int j=n+1; j<=n+n; ++j)
            {
                k2=bel[j];
                if(!mp[i][j-n]||k1!=k2)continue;
                g.push_back(j-n);
            }
            printf("%d",g.size());
            for(int j=0; j<g.size(); ++j)
                printf(" %d",g[j]);
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    linux上修改系统默认语言设置
    【计算机基础之编程语言】编程语言的发展
    【Java语言特性学习之四】常用集合
    【Java语言特性学习之三】Java4种对象引用
    【Java语言特性学习之二】反射
    【网络知识之七】QUIC(http3)
    【网络知识之六】UDP
    【网络知识之五】TCP
    【网络知识之四】HTTP/2
    【网络知识之三】HTTPS协议
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5502616.html
Copyright © 2011-2022 走看看