POJ2186(tarjan求连通分量)

来源:互联网 发布:c#数组去重的方法 编辑:程序博客网 时间:2024/05/01 15:39

题意:a喜欢b,b喜欢c,则a喜欢c 现在问被所有其他的牛喜欢的牛的只数

tarjan求强连通分量并缩点   判断缩点后的度数,度数为0的点超过一个则答案为0


Source Code

         
  • Source Code
    #include <iostream>#include "stdio.h"#include "stdlib.h"#include "string.h"#include "math.h"#include <algorithm>#include "vector"using namespace std;#define N 10002int outdgree[N]={0},cnt,ans,answer,low[N],dfn[N],instack[N],stac[N], belong[N],n,Bcnt,times,pos,a[N*5],b[N*5];vector <int> vec[N];void tarjan_scc(int v){    int w,l=vec[v].size();    times++;    low[v]=dfn[v]=times;    instack[v]=1;    stac[++pos]=v;    for(int i=0;i<l;i++)    {        w=vec[v][i];            if(!dfn[w]){                tarjan_scc(w);                low[v]=min(low[w],low[v]);            }            else if(instack[w])                low[v]=min(low[v],dfn[w]);    }    if(dfn[v]==low[v]){        Bcnt++;        do{            w=stac[pos--];            instack[w]=0;            belong[w]=Bcnt;        }while(w!=v);    }}void init(){    memset( low, 0 ,sizeof(low));    memset( dfn, 0 ,sizeof(dfn));    memset( instack, 0, sizeof(instack));    memset( stac,0, sizeof(stac));    memset( belong,0, sizeof(belong));    memset(outdgree,0,sizeof(outdgree));    Bcnt=0;times=0;pos=0;answer=0;cnt=0;}int main(void){    int m;    //freopen("2186","r",stdin);    while(cin>>n>>m)    {    init();    for(int i=1;i<=m;i++)    {        cin>>a[i]>>b[i];        vec[b[i]].push_back(a[i]);    }    for(int i=1;i<=n;i++)    {        if(!dfn[i])  tarjan_scc(i);    }    for(int i=1;i<=m;i++)        if(belong[a[i]]!=belong[b[i]])            outdgree[belong[a[i]]]++;    for(int i=1;i<=Bcnt;i++)        if(outdgree[i]==0) {            cnt++;            ans=i;        }    if(cnt>1)  cout<<0<<endl;    else if(cnt==0) cout<<0<<endl;    else{    for(int i=1;i<=n;i++)        if(belong[i]==ans) answer++;    cout<<answer<<endl;    }    for(int i=0;i<=n;i++)    vec[i].clear();}}

0 0
原创粉丝点击