1. 程式人生 > >「模板」 割點

「模板」 割點

turn putchar %d ref cst con edge GC www.

「模板」 割點

<題目鏈接>


不會點雙導致的 APIO 完掛。

本應該聯賽前學的東西,不及時學,就只有等到變回聯賽選手後再學了吧。

以及,以後放棄鏈式前向星,存圖一律指針鄰接表。

#include <algorithm>
#include <cstdio>
using std::min;
const int MAXN=100010;
bool cut[MAXN];
int n,m,DFN_num,ans,DFN[MAXN],low[MAXN];
struct Edge
{
    int to;
    Edge *nxt;
    Edge(int to=0,Edge* nxt=nullptr
):to(to),nxt(nxt){} ~Edge(void) { if(nxt!=nullptr) delete nxt; } }*head[MAXN]; void AddEdge(int u,int v) { head[u]=new Edge(v,head[u]); } void AddEdges(int u,int v) { AddEdge(u,v); AddEdge(v,u); } void Tarjan(int u,int father) { int st_num=0; DFN[u]=low[u]=++DFN_num; for
(Edge *i=head[u];i!=nullptr;i=i->nxt) { int v=i->to; if(!DFN[v]) { Tarjan(v,father); low[u]=min(low[u],low[v]); if(DFN[u]<=low[v] && u!=father) cut[u]=true; if(u==father) ++st_num; } low[u]=min(low[u],DFN[v]); } if
(u==father && st_num>1) cut[father]=true; } int main(int argc,char** argv) { scanf("%d %d",&n,&m); for(int i=1,x,y;i<=m;++i) { scanf("%d %d",&x,&y); AddEdges(x,y); } for(int i=1;i<=n;++i) if(!DFN[i]) Tarjan(i,i); for(int i=1;i<=n;++i) if(cut[i]) ++ans; printf("%d\n",ans); for(int i=1;i<=n;++i) { if(cut[i]) printf("%d ",i); delete head[i]; } putchar(\n); return 0; }

謝謝閱讀。

「模板」 割點