题目链接:C Cut ‘em all!
题意:
给出一个树,如果去掉一条边可以分成两个有偶数个点的连通块(子树)就可以去掉这条边,问最多能去掉几条。
思路:
1.如果奇数肯定去不了,怎么去都不可能分成多个偶数块的
2.如果是偶数,就从顶点1开始,当作父顶点开始dfs,(看了题解才知道dfs,真的菜)。dfs就是计算子树的顶点个数,如果子数是偶数个顶点,那么ans就可以++,然后把该子树标记成搜索过的,最后的答案要-1;因为整棵树肯定是偶数顶点,ans也会+1;
代码:
#include<iostream>
#include<vector>
#include<cstring>
#include<string>
using namespace std;
const int Max=1e5+5;
vector<int>v[Max]; //存路径
int vis[Max],ans=0; //vis 用来标记状态
int dfs(int x)
{
int son=0; //计算子节点个数
vis[x]=1;
for(int i=0;i<v[x].size();++i)
{
if(!vis[v[x][i]])
{
son+=dfs(v[x][i]); //对每个没搜过的节点搜,记录子树顶点。
}
}
if((son+1)%2==0)ans++; //偶数点的就++,因为整棵树还要加上根节点1个,所以son要+1。
return son+1;
}
int main()
{
memset(vis,0,sizeof(vis));
int n,l,r;
cin>>n;
if(n&1)
{
cout<<"-1";
return 0;
}
for(int i=1;i<n;++i)
{
cin>>l>>r;
v[l].push_back(r);
v[r].push_back(l);
}
dfs(1);
cout<<ans-1;
return 0;
}