Codeforces --- 982C Cut 'em all! DFS加贪心

题目链接:

https://cn.vjudge.net/problem/1576783/origin

输入输出:

Examples
inputCopy
4
2 4
4 1
3 1
outputCopy
1
inputCopy
3
1 2
1 3
outputCopy
-1
inputCopy
10
7 1
8 4
8 10
4 7
6 5
9 3
3 5
2 10
2 5
outputCopy
4
inputCopy
2
1 2
outputCopy
0
Note
In the first example you can remove the edge between vertices 11 and 44. The graph after that will have two connected components with two vertices in each.

In the second example you can‘t remove edges in such a way that all components have even number of vertices, so the answer is −1

题目大意:

这道题其实题意很简单,给你一棵树,让你删边,然后得到的子树节点个数要是偶数。

而边的个数在离散数学里定义是 m = n-1, 这个在建树的时候需要注意!

DFS的作用是统计这个节点连接的节点的个数,具体实现在代码中有注释。

下面是AC代码:

#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back
#include <string.h>

using namespace std;
const int MX = 1e5+10;
int vis[MX], sum[MX];
int n;
vector<int> G[MX];

int dfs(int x)
{
    for(int i = 0; i < G[x].size(); ++i)
    {
        int u = G[x][i];
        if(!vis[u])
        {
            vis[u] = 1; // 经过的点先标记一下
            sum[x] += dfs(u); //沿着点DFS
            vis[u] = 0; // 回溯
        }
    }
    sum[x]++; // 经过一个点则需要加一
    return sum[x];
}

int main()
{
    int ans = 0;
    memset(vis, 0, sizeof(vis));
    memset(sum, 0, sizeof(sum));
    scanf("%d", &n);
    for(int i = 1; i <= n-1; ++i) // 建树初始化m = n-1
    {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].pb(v);
        G[v].pb(u); // 无向图!
    }
    if(n%2) //节点为奇数则不可能都分为偶数节点的连通图
    {
        printf("-1\n");
        return 0;
    }
    vis[1] = 1; // 初始节点的vis先标记为一
    dfs(1);
    for(int i = 1; i <= n; ++i)
    {
        //cout << sum[i] << ‘ ‘;
        if(sum[i]%2 == 0) ans++; // 节点个数为偶数则减
    }
    //cout << endl;
    printf("%d\n", ans-1); //减一的理由是根节点节点数一定为偶数,但是其不能减。。
}

如有疑问,欢迎评论指出!

Codeforces --- 982C Cut 'em all! DFS加贪心

原文地址:https://www.cnblogs.com/mpeter/p/10295797.html

时间: 2024-10-20 12:11:37

Codeforces --- 982C Cut 'em all! DFS加贪心的相关文章

Codeforces 551C - GukiZ hates Boxes(二分加贪心)

题意: 就是n个学生帮助教授搬箱子, 箱子分成m 堆, 每个学生每秒可以选择的两个操作 操作1,为从i堆迈向第i+1堆, 操作2,从i-1堆箱子中帮忙抱走一个箱子 问抱走所有箱子的最少时间为多少, 每个学生每秒可以同时行动 题解: 二分时间   然后再当前时间下,一个一个派出所有的学生,使其走到他能走的最远距离 代码: #include<stdio.h> int flag, value[100005], value2[100005], n, m; void find(long long int

Codeforces 982 C. Cut &#39;em all!(dfs)

解题思路: 代码中有详细注解,以任意一点为根,dfs遍历这棵树. 每一个节点可能有好几个子树,计算每棵子树含有的节点数,再+1即为这整棵树的节点. 判断子树是否能切断与根之间的联系,如果子树含有偶数个节点,则这棵子树可以被切断. 注意: 若由于我们建立这棵树的时候不知道两个连接的节点谁是谁的父节点. 所以我们在dfs中加个标记,找出除父节点以外的其他节点. #include <bits/stdc++.h> using namespace std; typedef long long ll; l

CF982C Cut &#39;em all!

思路: 在深搜过程中,贪心地把树划分成若干个连通分支就可以了.划分的条件是某个子树有偶数个节点.注意到在一次划分之后并不需要重新计数,因为一个数加上一个偶数并不影响这个数的奇偶性. 实现: 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 100005; 4 vector<int> G[MAXN]; 5 bool vis[MAXN]; 6 int ans = 0; 7 int dfs(int u

CodeForces - 383C Propagating tree(dfs + 线段树)

题目大意: 给出一棵树,树上每个节点都有权值,然后有两个操作. 1 x val 在结点x上加上一个值val,x的儿子加上 -val,x的儿子的儿子加上 - (-val),以此类推. 2 x 问x节点的值. 思路分析: 每个节点上加值都是给自己的儿子节点加,而且这个是颗树. 比如样例上的,如果你给node 1加一个值,那么五个节点都加. 再给node 2加个值,2的儿子节点也加了,之前给1加的值也要加到2号节点的儿子. 所以你会发现节点的儿子会存在一个从属的关系. 这样的话,我们可以把所有节点从新

HDOJ 题目3966 Aragorn&#39;s Story(Link Cut Tree成段加减点权,查询点权)

Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5505    Accepted Submission(s): 1441 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lor

hdu 4004 (二分加贪心) 青蛙过河

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4004 题目意思是青蛙要过河,现在给你河的宽度,河中石头的个数(青蛙要从石头上跳过河,这些石头都是在垂直于河岸的一条直线上) 还有青蛙能够跳跃的 最多 的次数,还有每个石头离河岸的距离,问的是青蛙一步最少要跳多少米可以过河> 这是一道二分加贪心的题,从0到的河宽度开始二分,二分出一个数然后判断在这样的最小步数(一步跳多少距离)下能否过河 判断的时候要贪心 主要难在思维上,关键是要想到二分上去,能想到

Codeforces Round #613 (Div. 2)D(贪心,分治)

构造两颗深度为30的字典树(根节点分别是0和1),结点只有0和1,从根节点向下DFS,贪心取答案. 1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 vector<int>a; 5 int dfs(vector<int>b,int x){ 6 if(x<0||b.size()==0)//30位都枚举完毕或当前向量中没有数字就中止 7 return 0;

CodeForces 1141G Privatization of Roads in Treeland (贪心+DFS染色)

<题目链接> 题目大意: 给定一棵树,给每条边染色,如果一个结点的两条边是相同颜色的,那么这个结点就是不满意的.现在要求颜色最少的染色数,使得不满意结点数量<=k. 解题分析: 首先,贪心地想,因为题目允许有最多k个不满意的点,所以我们将所有点的度数从大到小排个序,度数第k+1大的点的度数就是最少的染色数.然后,主要就是给出染色的方案了,我们可以用DFS对整棵树的所有边进行染色,同时,染色的过程中,还要尽可能地保证所有节点周围的边所染的颜色都不重复.所以我让每个节点都维护了一个mark值

codeforces Gym 100187F F - Doomsday 区间覆盖贪心

F. Doomsday Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/F Description Doomsday comes in t units of time. In anticipation of such a significant event n people prepared m vaults in which, as they think, it will