您的位置:首页 > 其它

GYM 100030 I.Prohibition(贪心)

2017-03-05 14:55 666 查看
Description

求树的最小支配集

Input

第一行一整数n表示点数,之后n-1行每行两个整数u,v表示树上一条边(1<=n<=200)

Output

输出n个0或1,1表示该点被属于支配集

Sample Input

3

1 2

2 3

Sample Output

0 1 0

Solution

贪心,对于每个节点,看其儿子节点是否存在未被支配的节点,如果有则该点必须属于支配集;如果其儿子全部被支配且没有儿子属于支配集则该点必须属于未支配的节点,留给其父亲去支配即可(根节点特判);如果存在儿子属于支配集则该点已经被支配

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 11111
vector<int>g[maxn];
int n,res,ans[maxn];
void add(int u,int v)
{
g[u].push_back(v),g[v].push_back(u);
}
int dfs(int u,int fa)
{
int temp=INF;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(v==fa)continue;
temp=min(temp,dfs(v,u));
}
if(temp==INF)return 0;//叶子节点
if(temp==0)//存在没被支配的儿子节点
{
ans[u]=1;
return 1;
}
if(temp==1)return 2;//存在支配集中的儿子节点
if(u==1)ans[1]=1;
return 0;
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
while(~scanf("%d",&n))
{
if(n==1)
{
printf("1\n");
continue;
}
memset(ans,0,sizeof(ans));
res=0;
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);
add(u,v);
}
dfs(1,1);
for(int i=1;i<=n;i++)
printf("%d%c",ans[i],i==n?'\n':' ');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: