poj 2186 Popular Cows

强连通缩点

统计出度为0的点

若点多于1 ans=0;

否则 ans=这个强连通的点数

#include <iostream>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
const int maxn=10001;
int n,m;
struct node
{
    intto;
    struct node*next;
}e1[maxn],e2[maxn],*p;

int edgeini(struct node e[])
{
    for(inti=1;i<=n;i++) e[i].next=&e[i];
}

int edgemake(int from,int to,struct node e[])
{
       p=(struct node *)malloc(sizeof(struct node));
       p->next=e[from].next;
       e[from].next=p;
       p->to=to;
}

int min(int a,int b)
{
   if(a<b) return(a);
   return(b);
}

intlow[maxn],dfn[maxn],visit[maxn],text[maxn],stack[maxn],team[maxn];
int time,ret,top;
int tarjan(int u)
{
   dfn[u]=++time;
   low[u]=dfn[u];
   visit[u]=1;
   text[u]=1;
   stack[++top]=u;

    structnode *q;
   q=e1[u].next;
   while(q!=&e1[u])
    {
       if(!visit[q->to])
       {
           tarjan(q->to);
           low[u]=min(low[u],low[q->to]);
       }
       else if(text[q->to])
       {
           low[u]=min(low[u],dfn[q->to]);
       }
       q=q->next;

    }
   if(dfn[u]==low[u])
    {
       ret++;
       while(stack[top]!=u)
       {
           int v=stack[top];
           team[v]=ret;
           top--;
           text[v]=0;

           struct node *q;
           q=e1[v].next;
           while(q!=&e1[v])
           {edgemake(u,q->to,e1);q=q->next;}
           q=e2[v].next;
           while(q!=&e2[v])
           {edgemake(q->to,u,e1);q=q->next;}
       }
       team[stack[top]]=ret;
       text[stack[top]]=0;
       top--;
    }
}

int countout(int u)
{
    intans=0;
   p=e1[u].next;
   while(p!=&e1[u])
    {
       if(dfn[p->to]==low[p->to]&&p->to!=u)
       ans++;
       p=p->next;
    }
   return(ans);
}

int main()
{
    scanf("%d%d",&n,&m);
   edgeini(e1),edgeini(e2);
    for(inti=1;i<=m;i++)
    {
       int from,to;
       scanf("%d %d",&from,&to);
       edgemake(from,to,e1);
       edgemake(to,from,e2);
    }

   memset(text,0,sizeof(text));
   memset(visit,0,sizeof(visit));
   memset(team,0,sizeof(team));
   memset(low,0,sizeof(low));
   memset(dfn,0,sizeof(dfn));
   time=0;
    top=0;
    ret=0;
    for(inti=1;i<=n;i++)
   if(!visit[i]) tarjan(i);

    intsum=0,tmp;
    for(inti=1;i<=n;i++)
   if(low[i]==dfn[i])
   if(!countout(i)) {sum++;tmp=i;}

 

   if(sum>1) printf("0\n");
    else
    {
       int ans=0;
       for(int i=1;i<=n;i++)
       if(team[i]==team[tmp])
       ans++;
       printf("%d\n",ans);
    }

 

    return0;
}


 

你可能感兴趣的:(poj 2186 Popular Cows)