首页 > 代码库 > codevs 1332 上白泽慧音

codevs 1332 上白泽慧音

题目链接:http://codevs.cn/problem/1332/

题解:

  裸Tarjan,每次出栈操作时,记录当前强连通分量中的结点数,与ans1比较,并用ans2记录当前最大强连通分量的序号

 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define MAXN 5010 6 #define MAXM 50010 7 int n,m,time,cnt,heads[MAXN],DFN[MAXN],Low[MAXN],stack[MAXN],top,ans1,ans2,belong[MAXN]; 8 bool vis[MAXN]; 9 struct node10 {11     int v,next;12 }edge[MAXM];13 void add(int x,int y)14 {15     edge[++cnt].next=heads[x];16     heads[x]=cnt;17     edge[cnt].v=y;18 }19 void _(int x)//出栈 20 {21     int i,j=0;22     cnt++;//强连通分量序号更新 23     do24     {25         i=stack[top--];26         vis[i]=false;27         belong[i]=cnt;28         j++;29     }while(x!=i);30     if(j>=ans1)//更新最大强连通分量结点数和序号 31     {32         ans1=j;33         ans2=cnt;34     }35 }36 void tarjan(int x)37 {38     DFN[x]=Low[x]=++time;39     vis[x]=true;40     stack[++top]=x;41     for(int i=heads[x];i!=0;i=edge[i].next)42     {43         if(!DFN[edge[i].v])44         {45             tarjan(edge[i].v);46             Low[x]=min(Low[x],Low[edge[i].v]);47         }48         else if(vis[edge[i].v])Low[x]=min(Low[x],DFN[edge[i].v]);49     }50     if(DFN[x]==Low[x])_(x);51 }52 int main()53 {54     scanf("%d%d",&n,&m);55     for(int i=1;i<=m;i++)56     {57         int x,y,z;58         scanf("%d%d%d",&x,&y,&z);59         if(z==1)add(x,y);60         else61         {62             add(x,y);63             add(y,x);64         }65     }66     cnt=0;67     for(int i=1;i<=n;i++)68         if(!DFN[i])tarjan(i);69     printf("%d\n",ans1);70     for(int i=1;i<=n;i++)71     {72         if(belong[i]==ans2)printf("%d ",i);//如果该结点属于最大强连通分量,输出 73     }74     return 0;75 }

 

codevs 1332 上白泽慧音