absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] AGC12D
[破碎的状态] AGC010C

[破碎的状态] ARC063E

absi2011 posted @ 7 年前 in 刷题记录 with tags 小高考 集训队作业 瞎搞 atcoder , 862 阅读

link:http://arc063.contest.atcoder.jp/tasks/arc063_c

题意:

给你一颗树,有些点有初始权值

现在求一个方案(当然如果不存在方案输出No即可)(如果方案存在,输出Yes)

把所有点都赋一个权值,每条边的权值差恰好为1

(原来有权值就不能改了)

解法:

我们随便找个根

有一个性质,就是一个点的取值范围恰好是一个区间内所有的奇数/偶数

证明不太会,但是看起来是挺对的....

那么就是,每个点是不是在取值范围里面...就行了....

如果不是就No掉

如果都是,就Yes

方案的话,我们把根当成它的l值

然后dfs下去

每个如果l可以就l,不可以就r

这样就过了

证明.....不会!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#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;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter