hihoCoder1183 tarjan演算法應用之割邊和割點
阿新 • • 發佈:2018-12-30
#include<cstdio> #include<vector> #include<algorithm> using namespace std; int n,m,order=0; int low[20004],dfn[20004],father[20004],son[20004]; //father:父結點 son:子結點個數 vector<int> cutpoint,edge[20004]; vector< pair<int,int> > cutedge; void tarjan(int u) { dfn[u]=low[u]=++order; bool flag=false; for (int i=0;i<edge[u].size();i++) { int v=edge[u][i]; if(!dfn[v]) { son[u]++; father[v]=u; tarjan(v); if(low[v]>=dfn[u]) flag=true; //點u為割點 if(low[v]>dfn[u]) cutedge.push_back(make_pair(min(v,u),max(v,u))); //邊v-u為割邊 low[u]=min(low[u],low[v]); } else if(v!=father[u]) low[u]=min(low[u],dfn[v]); } //根節點若有兩棵或兩棵以上的子樹則該為割點 //非根節點若所有子樹節點均沒有指向u的祖先節點的回邊則為割點 if((father[u]==0&&son[u]>1)||(father[u]&&flag)) cutpoint.push_back(u); } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); edge[u].push_back(v),edge[v].push_back(u); } tarjan(1); sort(cutedge.begin(),cutedge.end()); sort(cutpoint.begin(),cutpoint.end()); if(0==cutpoint.size()) puts("Null"); else { printf("%d",cutpoint[0]); for (int i=1;i<cutpoint.size();i++) printf(" %d",cutpoint[i]); puts(""); } for(int i=0;i<cutedge.size();i++) printf("%d %d\n",cutedge[i].first,cutedge[i].second); }