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

来源:互联网 发布:mac 命令行 文件夹 编辑:程序博客网 时间:2024/05/23 17:46
 

                #67. 新年的毒瘤

辞旧迎新之际,喜羊羊正在打理羊村的绿化带,然后他发现了一棵长着毒瘤的树。

这个长着毒瘤的树可以用n个结点m 条无向边的无向图表示。这个图中有一些结点被称作是毒瘤结点,即删掉这个结点和与之相邻的边之后,这个图会变为一棵树。树也即无简单环的无向连通图。

现在给你这个无向图,喜羊羊请你帮他求出所有毒瘤结点。

 

样例一

input

6 61 21 32 42 54 65 6

output

34 5 6256MB

来源

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 }

 

0 0