首页 > 编程知识 正文

上白泽慧音能力,上白泽慧音眼睛

时间:2023-05-03 12:18:24 阅读:258674 作者:2018

题目链接:https://www.luogu.com.cn/problem/P1726

tarjan的一道模板题,t=1连一条单向边,t=2连一条双向边。tarjan跑一遍,一个绝对连通区域就是一个强连通分量。tarjan中每次找到一个强连通分量,记录这个强连通分量有多少个点。然后找到强连通分量最大的那个,从前往后找,就保证了字典序最小的优先,最后输出属于那个连通块的点即可。
代码如下

#include <bits/stdc++.h>using namespace std;const int maxn=5e3+5;const int maxm=1e5+5;int head[maxn];struct node{ int to,next;}edge[maxm];int cnt;void add(int x,int y){ edge[++cnt].next=head[x]; edge[cnt].to=y; head[x]=cnt;}int dfn_number,top,color;int dfn[maxn],low[maxn],col[maxn],stc[maxn],col_num[maxn];bool vis[maxn];void tarjan(int u){ dfn[u]=low[u]=++dfn_number; stc[++top]=u; vis[u]=1; for(int i=head[u];i;i=edge[i].next) { int v=edge[i].to; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { int len=1; vis[u]=false; col[u]=++color; while(stc[top]!=u) { vis[stc[top]]=false; col[stc[top--]]=color; len++; } top--; col_num[color]=len; }}int n,m;int opt,x,y;int main(){ scanf("%d %d",&n,&m); while(m--) { scanf("%d %d %d",&x,&y,&opt); if(opt==1) { add(x,y); } else { add(x,y); add(y,x); } } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); int ma=0,t; for(int i=1;i<=n;i++) { if(col_num[col[i]]>ma) { ma=col_num[col[i]]; t=col[i]; } //cout<<col[i]<<endl; } printf("%dn",ma); for(int i=1;i<=n;i++) { if(col[i]==t) printf("%d ",i); } return 0;}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。