码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-05-17 19:25:03      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

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 强连通分量+二分图增广判定

标签:

原文地址:http://www.cnblogs.com/shuguangzw/p/5502616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!