1. 程式人生 > >洛谷P3388 縮點

洛谷P3388 縮點

Tarjan入門題。
Code:

// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#define ll long long
#define maxn 100001
using namespace std;
struct Edge{
    int nxt,to;
}edge[maxn*2];
int num_edge,head[maxn],dfn[maxn],low[maxn],n,m,cnt[maxn],tot,cut;
stack
<int> s; inline void addedge(int from,int to){ edge[++num_edge].nxt=head[from]; edge[num_edge].to=to; head[from]=num_edge; } void tarjan(int x,int fa){ dfn[x]=low[x]=++cut; int child=0; // s.push(x); for(int i=head[x];i;i=edge[i].nxt){ int y=edge[i].to;
if(!dfn[y]){ tarjan(y,fa); low[x]=min(low[x],low[y]); if(low[y]>=dfn[x]&&x!=fa){ cnt[x]=1; } if(x==fa){ child++; } } // else if(!sccnum[y]){ low[x]=min(dfn[y],low[x]); }
if(child>=2&&x==fa){ cnt[x]=1; // } } // if(low[x]==dfn[x]){ // scc_cnt++; // for(;;){ // //num[vscc_cnt]++; // int y=s.top(); // tot[scc_cnt]+=a[y]; // s.pop(); // sccnum[y]=scc_cnt; // if(y==x) break; // } // } } int main(){ // memset(head,0,sizeof(head)); // memset(dfn,0,sizeof(dfn)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } for(int i=1;i<=n;i++){ if(dfn[i]==0){ tarjan(i,i); } } for(int i=1;i<=n;i++){ if(cnt[i]){ tot++; } // cout<<cnt[i]<<" "; } printf("%d\n",tot); for(int i=1;i<=n;i++){ if(cnt[i]){ printf("%d ",i); } } return 0; }