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;
}