[破碎的状态] ARC063E
link:http://arc063.contest.atcoder.jp/tasks/arc063_c
题意:
给你一颗树,有些点有初始权值
现在求一个方案(当然如果不存在方案输出No即可)(如果方案存在,输出Yes)
把所有点都赋一个权值,每条边的权值差恰好为1
(原来有权值就不能改了)
解法:
我们随便找个根
有一个性质,就是一个点的取值范围恰好是一个区间内所有的奇数/偶数
证明不太会,但是看起来是挺对的....
那么就是,每个点是不是在取值范围里面...就行了....
如果不是就No掉
如果都是,就Yes
方案的话,我们把根当成它的l值
然后dfs下去
每个如果l可以就l,不可以就r
这样就过了
证明.....不会!
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<math.h>
#include<time.h>
#include<vector>
#include<bitset>
#include<memory>
#include<utility>
#include<fstream>
#include<stdio.h>
#include<sstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
bool flag;
struct edge
{
int y;
edge * next;
};
edge * li[100005];
edge * new_edge()
{
static edge a[200005];
static int top=0;
return &a[top++];
}
void inserts(int x,int y)
{
edge * t=new_edge();
t->y=y;
t->next=li[x];
li[x]=t;
}
void insert_edge(int x,int y)
{
inserts(x,y);
inserts(y,x);
}
int l[100005],r[100005];
int w[100005];
bool vis[100005];
void dfs(int x)
{
vis[x]=true;
edge * t;
for (t=li[x];t!=0;t=t->next)
{
if (vis[t->y]) continue;
dfs(t->y);
l[x]=max(l[x],l[t->y]-1);
r[x]=min(r[x],r[t->y]+1);
}
if (l[x]>r[x])
{
flag=true;
}
if (w[x]==-1) return;
if (l[x]%2!=w[x]%2)
{
if (l[x]>-1000000) flag=true;
}
if (l[x]>w[x])
{
flag=true;
}
if (w[x]>r[x])
{
flag=true;
}
l[x]=w[x];
r[x]=w[x];
}
void dfs2(int x,int val)
{
if (w[x]==-1)
{
w[x]=val;
}
vis[x]=false;
edge * t;
for (t=li[x];t!=0;t=t->next)
{
if (vis[t->y])
{
int temp=val;
if (temp<l[t->y]) temp++; else temp--;
dfs2(t->y,temp);;
}
}
}
int main()
{
#ifdef absi2011
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
int n;
scanf("%d",&n);
int i;
for (i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x--;
y--;
insert_edge(x,y);
}
int q;
scanf("%d",&q);
for (i=0;i<n;i++)
{
l[i]=-10000000;
r[i]=200000000;
vis[i]=false;
w[i]=-1;
}
for (i=0;i<q;i++)
{
int x,y;
scanf("%d%d",&x,&y);
x--;
w[x]=y;
}
flag=false;
dfs(0);
if (flag)
{
puts("No");
return 0;
}
puts("Yes");
dfs2(0,l[0]);
for (i=0;i<n;i++)
{
printf("%d\n",w[i]);
}
return 0;
}
评论 (0)