#67. 新年的毒瘤
辞旧迎新之际,喜羊羊正在打理羊村的绿化带,然后他发现了一棵长着毒瘤的树。
这个长着毒瘤的树可以用n个结点m 条无向边的无向图表示。这个图中有一些结点被称作是毒瘤结点,即删掉这个结点和与之相邻的边之后,这个图会变为一棵树。树也即无简单环的无向连通图。
现在给你这个无向图,喜羊羊请你帮他求出所有毒瘤结点。
样例一
input
6 6 1 2 1 3 2 4 2 5 4 6 5 6
output
3 4 5 6 256MB
来源
UOJ Goodbye Jiawu
【思路】
无向图的割顶。
如果剩下的点组成一棵树,则满足边数为n-2。
那么“毒瘤”满足:1/非割顶;2/度数=m-(n-2)。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<iostream> 5 using namespace std; 6 7 const int maxn = 100000+10; 8 9 int pre[maxn],low[maxn],iscut[maxn],dfs_clock; 10 vector<int> G[maxn]; 11 12 int dfs(int u,int fa) { 13 int lowu=pre[u]=++dfs_clock; 14 int ch=0; 15 for(int i=0;i<G[u].size();i++) { 16 int v=G[u][i]; 17 if(!pre[v]) { 18 ch++; 19 int lowv=dfs(v,u); 20 lowu=min(lowu,lowv); 21 if(lowv>=pre[u]) iscut[u]=1; //只要有一个 22 } 23 else if(pre[v]<pre[u] && v!=fa) { 24 lowu=min(lowu,pre[v]); 25 } 26 } 27 if(fa<0 && ch==1) iscut[u]=0; 28 low[u]=lowu; 29 return lowu; 30 } 31 32 int read() { 33 char c=getchar(); 34 while(!isdigit(c)) c=getchar(); 35 int x=0; 36 while(isdigit(c)) 37 x=x*10+c-‘0‘ , c=getchar(); 38 return x; 39 } 40 41 int n,m; 42 int d[maxn],ans[maxn]; 43 44 int main() { 45 n=read(),m=read(); 46 int u,v; 47 for(int i=0;i<m;i++) { 48 u=read(),v=read(); 49 u--,v--; 50 d[u]++,d[v]++; 51 G[u].push_back(v),G[v].push_back(u); 52 } 53 dfs(0,-1); 54 int tot=0; 55 for(int i=0;i<n;i++) 56 if(!iscut[i] && d[i]==m-(n-2)) 57 ans[tot++]=i+1; 58 printf("%d\n",tot); 59 for(int i=0;i<tot;i++) printf("%d ",ans[i]); 60 return 0; 61 }
时间: 2024-11-04 23:57:05