版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/88368413
正题
题目链接:https://www.luogu.org/problemnew/show/P1726
题目大意
求最大的强联通分量和包含的点
解题思路
模板不解释。
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
const int N=5010,M=50100;
struct node{
int to,next;
}a[2*M];
stack<int> Stack;
int n,m,tot,cnt,num,ans,mark;
int ls[N],dfn[N],low[N],siz[N],in[N];
bool v[N];
void addl(int x,int y)
{
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;
}
void tarjan(int x)
{
Stack.push(x);v[x]=1;
dfn[x]=low[x]=++cnt;
for(int i=ls[x];i;i=a[i].next)
{
int y=a[i].to;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
}
else if(v[y])
low[x]=min(low[x],dfn[y]);
}
if(low[x]==dfn[x])
{
++num;
while(Stack.top()!=x)
{
int y=Stack.top();
Stack.pop();
in[y]=num;
siz[num]++;
v[y]=0;
}
Stack.pop();
v[x]=0;
siz[num]++;
in[x]=num;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addl(x,y);
if(z>1) addl(y,x);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++)
if(siz[in[i]]>ans){
ans=siz[in[i]];
mark=in[i];
}
printf("%d\n",ans);
for(int i=1;i<=n;i++)
if(in[i]==mark) printf("%d ",i);
}