1. 程式人生 > >CodeForces 982C Cut 'em all 【DFS】+【貪心】

CodeForces 982C Cut 'em all 【DFS】+【貪心】

emp || nbsp spa size int else https std

<題目鏈接>

題目大意:

一顆無向樹,現在問你最多能夠刪除多少條邊,使得最終分成的多個節點塊,每個節點塊所含節點數為偶數。

解題分析:

可以想到,如果以某個節點為根的子樹節點數為奇數(包括該節點本身),那麽肯定不會對該子樹進行割邊操作,因為割出的節點塊必然存在奇數的情況。所以我們先進行DFS,計算出每個節點以自己為根的子樹節點數,然後,因為要使割邊最大,所以我們貪心地在樹中,自下而上,遇到節點數為偶數的子樹,就將其從樹上割下,最後就能得到最大的割邊數量。

 1 #include <bits/stdc++.h>
 2 using namespace std;
3 4 #define N int(1e5+7) 5 int cnt,ans,num[N],head[N]; 6 struct Edge{ 7 int to,nxt; 8 }edge[N<<1]; 9 10 template<typename T> 11 inline T read(T&x){ 12 x=0;int f=0;char ch=getchar(); 13 while(ch<0||ch>9)f|=(ch==-),ch=getchar(); 14 while(ch>=
0 && ch<=9)x=x*10+ch-0,ch=getchar(); 15 return x=f?-x:x; 16 } 17 void addedge(int u,int v){ 18 edge[cnt].to=v,edge[cnt].nxt=head[u]; 19 head[u]=cnt++; 20 } 21 void dfs(int u,int fa){ 22 num[u]=1; 23 for(int i=head[u];~i;i=edge[i].nxt){ 24 int v=edge[i].to;
25 if(v==fa)continue; 26 dfs(v,u); 27 num[u]+=num[v]; 28 } 29 if(!(num[u]&1))num[u]=0,ans++; //將該偶數節點塊從樹上取下 30 } 31 int main(){ 32 int n;read(n); 33 cnt=0,ans=0;memset(head,-1,sizeof(head)); 34 for(int i=1;i<n;i++){ 35 int u,v;read(u);read(v); 36 addedge(u,v);addedge(v,u); 37 } 38 if(n&1)puts("-1"); //如果一開始n就為奇數,肯定不符合 39 else{ 40 dfs(1,-1); 41 ans--; //最後一個節點塊不需要進行割邊操作 42 printf("%d\n",ans); 43 } 44 }

2019-02-16

CodeForces 982C Cut 'em all 【DFS】+【貪心】