山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

uoj#67. 新年的毒瘤(割顶)

 

                #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 }

 

posted on 2015-12-18 17:42  hahalidaxin  阅读(342)  评论(0编辑  收藏  举报