poj 1904(强连通)

Posted 发牌员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1904(强连通)相关的知识,希望对你有一定的参考价值。

建有向图,男生向喜欢的女生建边,女生向国师给的最大匹配的男生建边,因为男生数等于女生数,所以如果可以存在x1娶y2使最大匹配数不变的话,那么x2也可以娶y1,这样就能成环,多对男女也一样

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <stack>
using namespace std;
const int maxn=4000+100;
const int maxm=200000+4000+200;//别忘了女孩还能建反响边到男孩
int low[maxn],dfn[maxn];
int pre[maxn];
int a[maxn];
int nn,cnn;
int insk[maxn];
bool vis[maxn];
int n,k;
stack<int> sk;
int hade[maxm];
struct note
{
    int next;
    int to;
}aa[maxm];
void addage(int fr,int to)
{
     aa[k].to=to;
     aa[k].next=hade[fr];
     hade[fr]=k++;
}
void tarjan(int u)
{     nn++;
    low[u]=dfn[u]=nn;
    insk[u]=1;
    vis[u]=1;
    sk.push(u);
  for(int i=hade[u];i!=-1;i=aa[i].next)
  {   int v=aa[i].to;
      if(!vis[v])
      {
          tarjan(v);
         low[u]=min(low[u],low[v]);
      }
      else if(insk[v])
      {
          low[u]=min(dfn[v],low[u]);
      }
  }
  if(low[u]==dfn[u])
  {
     int v;
     do
     {
         v=sk.top(); sk.pop();
          pre[v]=cnn;
          insk[v]=0;
      }
     while(v!=u);
        cnn++;
  }
}
void init()
{
    memset(hade,-1,sizeof(hade));
    memset(vis,0,sizeof(vis));
    memset(aa,0,sizeof(aa));
    while(sk.size()) sk.pop();
    memset(insk,0,sizeof(insk));
    memset(pre,0,sizeof(pre));
    k=0;
    nn=cnn=0;
}
int main()
{
    while(~scanf("%d",&n))
    {
        init();
        int m,to;
     for(int i=1;i<=n;i++)
     {
         scanf("%d",&m);
         for(int j=1;j<=m;j++)
         {
             scanf("%d",&to);
             addage(i,to+n);
         }
     }
      for(int i=1;i<=n;i++)
      {
          scanf("%d",&to);
          addage(to+n,i);
      }
        for(int i=1;i<=n;i++)
            if(!vis[i]) tarjan(i);
        int cnt=0;
       for(int u=1;u<=n;u++)
       {
          for(int i=hade[u];i!=-1;i=aa[i].next)//王子只能娶他喜欢的女生
          {
              int v=aa[i].to;
              if(pre[v]==pre[u])
                a[cnt++]=v-n;
          }
            sort(a,a+cnt);
            printf("%d",cnt);
             for(int i=0;i<cnt;i++)
               printf(" %d",a[i]);
               printf("\n");
               cnt=0;
       }

    }
    return 0;
}

 

以上是关于poj 1904(强连通)的主要内容,如果未能解决你的问题,请参考以下文章

poj 1904(强连通)

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

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

强连通分量目录

POJ 3114 Countries in War(强连通+最短路)

POJ1236DAG转强连通图