◇例题·III◇ 木と整数 / Integers on a Tree

只需要一个美妙的转换,这道题就会变得无比美妙……

来源:+AtCoder 2148(ARC-063 E)+


◆ 题目大意

给定一棵n个节点(节点被编号为1~n)的树,有K (1≤K≤n) 个节点已经被填上一个数字,现在你需要把剩余的节点填上数字,使得被同一条边相连的两个节点数值相差恰好为1。

若可以实现,先输出一行"Yes",接下来n行,每行输出一个整数,第i+1行表示节点i的数值;否则输出"No"。

若最初填上的数值没有满足相连两点差为1,也判定为No。


◆ 解析

这道题的解法非常美妙~

首先我第一个思路是BFS。一个很简单的结论,每向外延伸一个节点,节点的可取值就会增加2——最大值增加1,最小值减小1。这是很直观的:

于是我储存了每一个节点的可取值范围 [最小值,最大值] ,由于一些点已经给出值,这些点的最大值等于最小值。

另外一个简单结论就是——相邻节点的奇偶性相反(就不证明了)

于是我把已经固定值的节点作为起点:初始化它的最大值、最小值为它的定值;把它push进队列里。

利用BFS,从已知取值范围为[Au,Bu]的点u向外扩展到点v,若v没有确定范围,则v的范围暂时确定为[Au-1,Bu+1];若已经确定范围为[Av,Bv],则先判断点v的奇偶性是否冲突(只需要判断最大值或最小值的奇偶性是否冲突就可以了[为什么?想一想就知道了!]),若冲突,则直接输出"No",否则更新v的范围为[max{Av,Au+1},min{Bv,Au-1}],若v的取值范围为空(最大值小于最小值),则输出"No"。

最后遍历一遍树,就可以得到所有点的取值了……

唠了这么多……其实这个想法Wa了 QwQ

(肯定被打 @( ◕ x ◕ )@)

下面是正解……

若两点u,v满足v的数值小于u,且u,v之间有满足条件的解,则u到v的路径上的节点的数值存在两种情况:

扩展到多个点也是满足的。

如何实现?

定义一个优先队列(小根堆),按节点的数值为关键字排序。我们可以把优先队列的类型定为 pair<int,int> ,因为pair<>的大小关系只取决于第一个元素(.first),所以我们把节点的值作为first,节点编号作为second,就可以实现按数值为关键字排序。同时定义答案数组 ans[]。先把已知节点的答案定为已知值,并push入队列。

每次取出队列的开头,也就是已知值最小且仍可能更新其他节点值的节点。以该节点u为起始点向它相连的点v更新,若ans[v]没有赋值,则直接赋为ans[v]=ans[u]+1;否则判断 |ans[v]-ans[u]| 是否等于1,不满足则输出No。

其他的就请详见代码了~


◆ 源代码

 /*Lucky_Glass*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
const int MAXN=int(1e5),INF=int(1e9);
vector<int> lnk[MAXN+];
//邻接表储存图
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > que;
//定义小根堆,first为节点数值,second为节点编号
int ans[MAXN+];
//储存已知值
int n,m;
int main()
{
scanf("%d",&n);
for(int i=,u,v;i<n;i++)
scanf("%d%d",&u,&v),
lnk[u].push_back(v),
lnk[v].push_back(u);
scanf("%d",&m);
fill(ans,ans+MAXN+,INF); //初始化
for(int i=,x,y;i<m;i++)
scanf("%d%d",&x,&y),
que.push(make_pair(y,x)), //将已知节点push进队列
ans[x]=y;
while(!que.empty())
{
int u=que.top().second,val=que.top().first; //取出已知值最小且可能更新周围节点的节点
/*什么叫可能更新周围节点?每一次更新一定会更新完一个节点的全部相邻节点,且这些节点不再更新,因此每一个节点在队列里只出现一次*/
que.pop();
for(int i=;i<lnk[u].size();i++)
{
int v=lnk[u][i];
if(ans[v]==INF)
ans[v]=val+,que.push(make_pair(ans[v],v)); //更新值
if(fabs(ans[v]-ans[u])!=) //不满足条件
{
printf("No\n");
return ;
}
}
}
printf("Yes\n");
for(int i=;i<=n;i++)
printf("%d\n",ans[i]);
return ;
}

The End

Thanks for reading!

- Lucky_Glass

(Tab:如果我有没讲清楚的地方可以直接在邮箱lucky_glass@foxmail.com email我,在周末我会尽量解答并完善博客~)

【例题收藏】◇例题·III◇ 木と整数 / Integers on a Tree的更多相关文章

  1. 【例题收藏】◇例题·6◇ 电压机制(voltage)

    ◆例题·6◆ 电压机制 周六日常模拟赛……已经不知道该说什么了(感觉做不出来的都是好题) ▷ 题目 (终于不用自己翻译英文题了╮(╯-╰)╭) [问题描述] 科学家在“无限神机”(Infinity M ...

  2. 【例题收藏】◇例题·V◇ Gap

    ◇例题·V◇ Gap 搜索训练开始了……POJ的数据比ZOJ强多了!!看来不得不写正解了 +传送门+ ◇ 题目 <简要翻译> 有一个四行九列的矩阵——在第1~4行.2~8列上填上数字 11 ...

  3. 【例题收藏】◇例题·II◇ Berland and the Shortest Paths

    ◇例题·II◇ Berland and the Shortest Paths 题目来源:Codeforce 1005F +传送门+ ◆ 简单题意 给定一个n个点.m条边的无向图.保证图是连通的,且m≥ ...

  4. 【例题收藏】◇例题·IV◇ Wooden Sticks

    ◇例题·IV◇ Wooden Sticks 借鉴了一下 Candy? 大佬的思路 +传送门+ (=^-ω-^=) 来源:+POJ 1065+ ◆ 题目大意 有n个木棍以及一台处理木棍的机器.第i个木棍 ...

  5. 【例题收藏】◇例题·I◇ Snuke's Subway Trip

    ◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...

  6. HDU 1028 Ignatius and the Princess III dp整数划分

    http://acm.hdu.edu.cn/showproblem.php?pid=1028 dp[i][j]表示数值为i,然后最小拆分的那个数是j的时候的总和. 1 = 1 2 = 1 + 1 . ...

  7. POJ3468--A Simple Problem with Integers(Splay Tree)

    虽然有点难,但是这套题都挂了一个月了啊喂…… 网上模板好多……最后还是抄了kuangbin聚聚的,毕竟好多模板都是抄他的,比较习惯…… POJ 3468 题意:给n个数,两种操作,区间整体加一个数,或 ...

  8. 【ARC063E】Integers on a tree

    Description 给定一棵\(n\)个点的树,其中若干个点的权值已经给出.现在请为剩余点填入一个值,使得相邻两个点的差的绝对值恰好为1.请判断能否实现,如果能,请将方案一并输出. Solutio ...

  9. 2018.09.22 atcoder Integers on a Tree(构造)

    传送门 先考虑什么时候不合法. 第一是考虑任意两个特殊点的权值的奇偶性是否满足条件. 第二是考虑每个点的取值范围是否合法. 如果上述条件都满足的话就可以随便构造出一组解. 代码: #include&l ...

随机推荐

  1. jQuery源码解读 --- 整体架构

    最近学习比较忙,感觉想要提高还是要读源码,所以准备考试这个考试结束就开始读jquery源码啦,加油~

  2. mysql-proxy读写分离,负载均衡

    配置mysql-proxy,创建主配置文件 cd /usr/local/mysql-proxy mkdir lua #创建脚本存放目录 mkdir logs #创建日志目录 cp share/doc/ ...

  3. Android自定义进度条-带文本(文字进度)的水平进度条(ProgressBar)

    水平进度条,显示进度的文本随着进度而移动. 效果如下,截的静态图. 代码如下 TextProgressBar.java public class TextProgressBar extends Pro ...

  4. 二维码项目实例为二维码添加logo

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. html和Url转码与解码

    JS (JQuery)对Html.URL的编码与解码 首先引入JQuery文件 1.js对Html编码 function htmlEncode(value){ return $('<div/&g ...

  6. iOS UIWebView 和 WKWebView 的 cookie 获取,设置,删除

    Cookie简介说到Cookie,或许有些小伙伴会比较陌生,有些小伙伴会比较熟悉.如果项目中,所有页面都是纯原生来实现的话,一般Cookie这个东西或许我们永远也不会接触到.但是,这里还是要说一下Co ...

  7. java基础:JDK环境安装

    根据操作系统位数(32/64,一般64位向下兼容),项目要求版本,下载对应JDK安装包 配置环境变量 JAVA_HOME C:\Program Files\Java\jdk1.7.0_80 PATH ...

  8. 【转】大数据批处理框架 Spring Batch全面解析

    如今微服务架构讨论的如火如荼.但在企业架构里除了大量的OLTP交易外,还存在海量的批处理交易.在诸如银行的金融机构中,每天有3-4万笔的批处理作业需要处理.针对OLTP,业界有大量的开源框架.优秀的架 ...

  9. Mac Postman app使用方法

    Postman是一种网页调试与发送网页http请求的chrome插件.我们可以用来很方便的模拟get或者post或者其他方式的请求来调试接口.本文是使用的Mac端的app.利用第三方平台LeanClo ...

  10. innerHTML动态添加html代码和脚本兼容性问题处理方法

    给某个元素的innerHTML赋值,并使得值中的js代码有效(兼容多个浏览器) 症状:给某个元素的 innerHTML 设置值时,如果提供的 HTML 代码中包含js脚本,很多时候这些脚本无效,或者在 ...