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 }
时间: 2024-08-28 19:12:23

uoj#67. 新年的毒瘤(割顶)的相关文章

uoj 67 新年的毒瘤 tarjan求割点

#67. 新年的毒瘤 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/67 Description 辞旧迎新之际,喜羊羊正在打理羊村的绿化带,然后他发现了一棵长着毒瘤的树. 这个长着毒瘤的树可以用 n 个结点 m 条无向边的无向图表示.这个图中有一些结点被称作是毒瘤结点,即删掉这个结点和与之相邻的边之后,这个图会变为一棵树.树也即无简单环的无向连通图. 现在给你这个无向图,喜羊羊请你帮他求出所有毒瘤结点. I

UOJ#67 新年的毒瘤 tarjan

题目传送门 题意:给出一个$N$个点.$M$条边的无向图,找出其中的点,满足去掉该点与和它相连的边之后,这个图会变成一棵树.$N , M \leq 10^5$ 说是毒瘤,真的不毒瘤 思考一下,我们需要找的就是度为$M - (N - 1 - 1)$且不是割点的点,直接tarjan即可 想起来在某luogu题解里把tarjan写成targan 1 #include<bits/stdc++.h> 2 #define MAXN 100001 3 using namespace std; 4 5 inl

UOJ #67 新年的毒瘤

题目描述: 有一幅 n 个点 m 条边的图,问单独删掉哪些点,可以使原图变成一棵树.(保证至少有一个解) 解题思路: 注意到树的性质是有 n 个点,n - 1 条边的联通图.而删掉一个点后新图有n-1个点,所以需要选择的点的度数是 m - ( n - 2 ).而要保证新图联通,所以要先Tarjan找割点,不要删割点就可以了. 代码: #include <cstdio> #include <cstring> #include <algorithm> using names

【UOJ#67】新年的毒瘤(Tarjan)

[UOJ#67]新年的毒瘤(Tarjan) 题面 UOJ 题解 一棵\(n\)个节点的树显然有\(n-1\)条边,在本题中意味着删去一个点之后还剩下\(n-2\)条边.那么找到所有度数为\(m-(n-2)\)的点就好了.但是因为是一棵树,所以联通,所以割点不是答案. #include<iostream> #include<cstdio> using namespace std; #define ll long long #define MAX 100100 inline int r

hdu 4587(枚举+割顶)

TWO NODES Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 2354    Accepted Submission(s): 780 Problem Description Suppose that G is an undirected graph, and the value of stab is defined as fol

POJ 1144 Network【割顶】

学习的这一篇:https://www.byvoid.com/blog/biconnect 割顶:对于无向图G,如果删除某个点u后,连通分量数目增加,称u为图的关节点或者割顶 u为割顶的条件: (1)u不为树根,以u的任一子节点为根的子树中没有一个点有返回u的祖先的反向边(返祖边) (2)u为树根,且u有多于一个子树 紫书上有证明 即为,祖先与每一棵子树之间都有返祖边的话(即,删除u点之后,以v为根的整棵子树都可以通过这条返祖边连回到f),该点不是割顶,如果祖先与它的其中一棵子树缺少返祖边的话,那

图论(无向图的割顶):POJ 1144 Network

Network Description A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting several places numbered by integers from 1 to N . No two places have the same number. The lines are bidirectional and always connect

UVA - 315 Network 和 UVA - 10199 (求割顶)

链接 :  http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20837 http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21278 求割顶的裸题. UVA - 315 #include <algorithm> #include <iostream> #include <sstream> #include <cstrin

【模板】无向图的割顶

无向图的割顶: Vector <int> G[] :邻接表存图 Int pre[] :存储时间戳 Int low[] : u及其后代所能连回的最早的祖先的pre值 Int iscut[] : =true表示是割顶,=false不是割顶 Dfs函数在主函数调用时,fa预设为-1. vector <int> G[MAXN]; int pre[MAXN],iscut[MAXN],low[MAXN],dfs_clock; int dfs(int u,int fa) { int lowu=p