https://vjudge.net/problem/Gym-101482H
题目大意:给一棵树,每个节点可以有两个,但是任意相邻的两个节点,最起码要有个是相等的。且这个相等的可以计算到贡献里面,问怎么构造使得贡献最大。
思路:贪心的想一下,假设父节点是,那么儿子节点要有个和它相等的,另外一个肯定要取新的值,假设为,那么不难想到一种构造方式:注意的时候特判一下,因为这种情况下显然不如更优。‘
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-10
#define pr pair<int,int>
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;
}