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

poj 1904(强连通)

时间:2017-10-13 12:34:01      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:ons   最大匹配   cstring   连通   scanf   ret   iostream   size   include   

建有向图,男生向喜欢的女生建边,女生向国师给的最大匹配的男生建边,因为男生数等于女生数,所以如果可以存在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(强连通)

标签:ons   最大匹配   cstring   连通   scanf   ret   iostream   size   include   

原文地址:http://www.cnblogs.com/Wangwanxiang/p/7660074.html

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