输入
第1行:2个正整数,N,M。表示点的数量N,边的数量M。1≤N≤20,000, 1≤M≤100,000
第2..M+1行:2个正整数,u,v。表示存在一条边(u,v),连接了u,v两台服务器。1≤u<v≤N
保证输入所有点之间至少有一条连通路径。
输出
第1行:若干整数,用空格隔开,表示满足要求的服务器编号。从小到大排列。若没有满足要求的点,该行输出Null
第2..k行:每行2个整数,(u,v)表示满足要求的边,u<v。所有边根据u的大小排序,u小的排在前,当u相同时,v小的排在前面。若没有满足要求的边,则不输出
/* *********************************************** Author :devil Created Time :2016/6/9 14:8:23 ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=20010; int dfn[N],low[N],f[N],cou=1; vector<int>eg[N]; vector<int>point; vector<pair<int,int> >edge; void dfs(int u) { bool add=0; int child=0; dfn[u]=low[u]=cou++; for(int i=0;i<eg[u].size();i++) { int v=eg[u][i]; if(v==f[u]) continue; if(!dfn[v]) { child++; f[v]=u; dfs(v); low[u]=min(low[u],low[v]); if(!add&&((!f[u]&&child>1)||(f[u]&&low[v]>=dfn[u]))) { point.push_back(u); add=1; } if(low[v]>dfn[u]) edge.push_back(make_pair(min(u,v),max(u,v))); } else low[u]=min(low[u],dfn[v]); } } int main() { //freopen("in.txt","r",stdin); int n,m,u,v; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); eg[u].push_back(v); eg[v].push_back(u); } dfs(1); if(!point.size()) printf("Null "); else { sort(point.begin(),point.end()); printf("%d",point[0]); for(int i=1;i<point.size();i++) printf(" %d",point[i]); printf(" "); } sort(edge.begin(),edge.end()); for(int i=0;i<edge.size();i++) printf("%d %d ",edge[i].first,edge[i].second); return 0; }