1. 程式人生 > >Codeforces --- 982C Cut 'em all! DFS加貪心

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

奇數 dfs img mes const () set eve fin

題目鏈接:

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); //減一的理由是根節點節點數一定為偶數,但是其不能減。。 }
View Code

如有疑問,歡迎評論指出!

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