GYM 101102 L.Starry Night(贪心+dfs)
2017-03-17 14:34
357 查看
Description
给出一棵树,问通过删点最多能够把这棵树变成多少个星星,星星就是一个点周围不小于三条链且不能有分叉
Input
第一行一整数T表示用例组数,每组用例首先输入一整数n表示点数,之后n-1行每行两个整数u和v表示树上一条边(1<=n<=1e5)
Output
输出适当删点后最多能够得到多少个星星
Sample Input
1
9
1 2
3 2
5 1
3 7
1 4
3 8
1 6
3 9
Sample Output
2
Solution
贪心,每次从末端删去三叉小星星,对于一个点,打两种标记,第一种是被删掉的标记vis1[i],第二种是作为其某个儿子的一叉的标记vis2[i],任意选点为根开始dfs,统计每个点u(父亲节点为f)没被删掉的儿子节点数目num
1.如果u被打上了vis1的标记就不用管了,因为已经被删除了
2.如果u点被打上了vis2标记,说明其被某些儿子作为一叉了(可能有多个,所以不能在dfs到其儿子打标记时就给答案加上了,而是在这一点加,因为u点只能作为一个儿子的一叉),给答案加一,给f打上vis1的标记表示要删除f才能成全u点作为其某个儿子的一叉
3.如果u点两种标记都没被打
num=2说明u点往下只有两个叉,只能给其父亲f打上vis2的标记表示u点要是想成为一个星星就需要f作为u的一叉
num>2说明u只需要其儿子们作为叉就能形成一个星星,答案加一,给其父亲f打上vis1的标记表示f为了成全其儿子u作为一个星星的中心要被删除掉
Code
给出一棵树,问通过删点最多能够把这棵树变成多少个星星,星星就是一个点周围不小于三条链且不能有分叉
Input
第一行一整数T表示用例组数,每组用例首先输入一整数n表示点数,之后n-1行每行两个整数u和v表示树上一条边(1<=n<=1e5)
Output
输出适当删点后最多能够得到多少个星星
Sample Input
1
9
1 2
3 2
5 1
3 7
1 4
3 8
1 6
3 9
Sample Output
2
Solution
贪心,每次从末端删去三叉小星星,对于一个点,打两种标记,第一种是被删掉的标记vis1[i],第二种是作为其某个儿子的一叉的标记vis2[i],任意选点为根开始dfs,统计每个点u(父亲节点为f)没被删掉的儿子节点数目num
1.如果u被打上了vis1的标记就不用管了,因为已经被删除了
2.如果u点被打上了vis2标记,说明其被某些儿子作为一叉了(可能有多个,所以不能在dfs到其儿子打标记时就给答案加上了,而是在这一点加,因为u点只能作为一个儿子的一叉),给答案加一,给f打上vis1的标记表示要删除f才能成全u点作为其某个儿子的一叉
3.如果u点两种标记都没被打
num=2说明u点往下只有两个叉,只能给其父亲f打上vis2的标记表示u点要是想成为一个星星就需要f作为u的一叉
num>2说明u只需要其儿子们作为叉就能形成一个星星,答案加一,给其父亲f打上vis1的标记表示f为了成全其儿子u作为一个星星的中心要被删除掉
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; #define INF 0x3f3f3f3f #define maxn 111111 int T,n,vis1[maxn],vis2[maxn],ans; vector<int>g[maxn]; void dfs(int u,int f) { int num=0; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(v==f)continue; dfs(v,u); if(!vis1[v])num++; } if(!vis1[u]) { if(vis2[u])ans++,vis1[f]=1; else if(num>=3)ans++,vis1[f]=1; else if(num==2)vis2[f]=1; } } int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++)g[i].clear(); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); g[u].push_back(v),g[v].push_back(u); } memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); ans=0; dfs(1,0); printf("%d\n",ans); } return 0; }
相关文章推荐
- GYM 101102 B.The Little Match Girl (贪心)
- Gym - 101102B B. The Little Match Girl 贪心、数论、分步
- The Little Match Girl Gym - 101102B 【贪心, 上下界规律】
- poj 3900 dfs搜索剪枝+后缀和预处理+贪心
- hdu 5695 Gym Class 贪心+拓扑
- Codeforeces Gym-101064I Protecting the Central Park [dfs]
- codeforces_679B. Bear and Tower of Cubes(贪心+二分+dfs)
- Kattis - horrorfilmnight 【贪心】
- GYM 100796 C.Minimax Tree(dfs)
- GYM 100801 E.Easy Arithmetic(贪心)
- codeforces 700B Connecting Universities 贪心dfs
- HDU 4582 DFS spanning tree(DFS+贪心)(2013ACM-ICPC杭州赛区全国邀请赛)
- Starry Starry Night
- 洛谷 2279 [HNOI2003] 消防局的设立 贪心+dfs
- UVA 1267 - Network(贪心DFS)
- Gym 101606E 【贪心+sort】
- CodeforcesGym - 101102D. Rectangles 单调栈+dp优化
- GYM 100030 G.Procrastination(贪心)
- GYM 100488 G.Change-making Problem(贪心)
- [BZOJ1193][HNOI2006]马步距离(贪心+dfs)