codeforces gym101572 H Hyacinth 贪心+构造

https://vjudge.net/problem/Gym-101482H
codeforces gym101572 H Hyacinth 贪心+构造_第1张图片

题目大意:给一棵树,每个节点可以有两个 v a l u e value value,但是任意相邻的两个节点,最起码要有 1 1 1 v a l u e value value是相等的。且这个相等的 v a l u e value value可以计算到贡献里面,问怎么构造使得贡献最大。

思路:贪心的想一下,假设父节点是 a 、 b a、b ab,那么儿子节点要有 1 1 1个和它相等的,另外一个肯定要取新的值,假设为 b 、 c b、c bc,那么不难想到一种构造方式: ( a , b ) 、 ( b , c ) 、 ( c , d ) … … (a,b)、(b,c)、(c,d)…… (a,b)(b,c)(c,d)注意 n = 2 n=2 n=2的时候特判一下,因为这种情况下显然 ( a , b ) 、 ( b , c ) (a,b)、(b,c) (a,b)(b,c)不如 ( a , b ) 、 ( a , b ) (a,b)、(a,b) (a,b)(a,b)更优。‘

#include
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pr pair
using namespace std;
typedef long long ll;

const int maxn=1e4+5;

struct Edge
{
     
    int to,nxt;
}edge[maxn<<1];

int n,tot,cur=0;
int head[maxn],ans[maxn][2],f[maxn];

inline void addedge(int u,int v)
{
     
    edge[++tot].to=v,edge[tot].nxt=head[u],head[u]=tot;
}

void dfs(int u,int fa,bool pos)
{
     
    int v,ct=0;
    ans[u][0]=ans[fa][pos];
    ans[u][1]=++cur;//分配一个新的
    for(int i=head[u];i;i=edge[i].nxt)
    {
     
        v=edge[i].to;
        if(v==fa)
            continue;
        ++ct;
        dfs(v,u,ct&1);
    }
}

int main()
{
     
    scanf("%d",&n);
    int u,v;
    for(int i=1;i<n;i++)
    {
     
        scanf("%d%d",&u,&v);
        addedge(u,v),addedge(v,u);
    }
    if(n==2)
    {
     
        ans[1][0]=ans[2][0]=1;
        ans[1][1]=ans[2][1]=2;
    }
    else
    {
     
        ans[0][0]=++cur;
        dfs(1,0,0);
    }
    for(int i=1;i<=n;i++)
        printf("%d %d\n",ans[i][0],ans[i][1]);
    return 0;
}

你可能感兴趣的:(比赛补题,贪心,构造法)