poj 3180

    技术2022-05-19  19

         题目好长好啰嗦。。。其实是水题一道,就是找出结点数大于1的强连通分量的个数。此处用tarjan实现。

         以下是代码:

     

     

    #include<cstdio>#include<cstring>#include<iostream>using namespace std;const int N=30000;const int M=70000;struct node{ int u,v; int next;}edge[M];int head[N],num;int cnt[N],dep[N],Bcnt,dindex,low[N],stack[N],top;bool instack[N];int n,m;void init(){ int i; for(i=0;i<=n+3;i++) {  head[i]=-1;  cnt[i]=0; } num=0;}void addege(int u,int v){ edge[num].u=u; edge[num].v=v; edge[num].next=head[u]; head[u]=num++;}void tarjan(int i){ int j,v; dep[i]=low[i]=++dindex; instack[i]=true; stack[++top]=i; for(j=head[i];j!=-1;j=edge[j].next) {  v=edge[j].v;  if(!dep[v])  {   tarjan(v);   if(low[v]<low[i])    low[i]=low[v];  }  else if(instack[i] && dep[v]<low[i])   low[i]=dep[v]; } if(dep[i]==low[i]) {  Bcnt++;  do  {   j=stack[top--];   instack[j]=false;   cnt[Bcnt]++;  }while(j!=i); }}void solve(){ int i; top=Bcnt=dindex=0; memset(dep,0,sizeof(dep)); memset(instack,0,sizeof(instack)); for(i=1;i<=n;i++)  if(!dep[i])  {   tarjan(i);  }}int main(){ scanf("%d%d",&n,&m); init(); int i; for(i=1;i<=m;i++) {  int a,b;  scanf("%d%d",&a,&b);  addege(a,b); } solve(); int cout=0; for(i=1;i<=Bcnt;i++)  if(cnt[i]>=2) cout++; printf("%d/n",cout); return 0;}

    最新回复(0)