题目链接:https://www.luogu.org/problem/P1726
AC代码:
/*
强连通缩点板子题,缩点之后找到最大的一个强连通分量就行;
*/
#include<bits/stdc++.h>
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const int N=1e5+10;
struct node
{
int v,ne;
}q[N];
int f[N],low[N],dfn[N],vis[N],sum[N];
int belong[N],m,n,e,top,cnt;
stack<int>sta;
void add(int a,int b)
{
q[e].v=b;
q[e].ne=f[a];
f[a]=e++;
}
void tarjan(int now,int pre)
{
vis[now]=1;
low[now]=dfn[now]=++top;
sta.push(now);
for(int i=f[now];i!=-1;i=q[i].ne)
{
int v=q[i].v;
if(!dfn[v])
{
tarjan(v,now);
low[now]=min(low[now],low[v]);
}
else if(vis[v])
low[now]=min(low[now],dfn[v]);
}
if(low[now]==dfn[now])
{
int v,se=0;
cnt++;
while(true)//缩点
{
se++;
v=sta.top();
sta.pop();
belong[v]=cnt;//记录每个点属于哪个强连通分量
vis[v]=0;
if(v==now) break;
}
sum[cnt]=se;//记录每个强连通分量的大小
}
}
int main()
{
e=top=cnt=0;
memset(f,-1,sizeof(f));
scanf("%d %d",&n,&m);
int a,b,c;
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&a,&b,&c);
if(c==1) add(a,b);
else
{
add(b,a);
add(a,b);
}
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i,-1);
}
int u,maxx=0;
for(int i=1;i<=cnt;i++)
{
if(sum[i]>maxx)
{
u=i;
maxx=sum[i];
}
}
printf("%d\n",maxx);
for(int i=1;i<=n;i++)
{
if(belong[i]==u)
printf("%d ",i);
}
printf("\n");
return 0;
}