POJ 1904 King's Quest 强连通分量+二分图增广判定

Posted shuguangzw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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("\\n");
    }
    return 0;
}
View Code

 

以上是关于POJ 1904 King's Quest 强连通分量+二分图增广判定的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1904 King's Quest 强连通分量+二分图增广判定

King's Quest POJ - 1904(强连通分量)

POJ3682 King Arthur's Birthday Celebration

POJ3682King Arthur's Birthday Celebration(数学期望||概率DP)

poj1904 完美匹配+Tarjan

POJ1904(有向图缩点+输入输出挂参考)