第一次网络赛…(继NOIP 2017 之后的第一场竞赛),参加了Beginner(初学者)比赛。感觉不错,好像是第 24 名,也算是给祖国涨了脸吧 <( ̄ˇ ̄)/。
那么D题(最后一题),其实我还有50分钟的时间…于是我就…想了30分钟 (oh!),想了很多种方法,像并查集、动态规划什么的都想过,只是确实能力有限,写不了并查集(动态规划被我否认了),误打误撞,我决定暴力一下 —— 于是我加了一点可行性剪枝。然而这是官方标程!!!
Time limit : 2sec / Memory limit : 256MB
Score : 400 points
There are N people standing on the x-axis. Let the coordinate of Person i be xi. For every i, xi is an integer between 0 and 109 (inclusive). It is possible that more than one person is standing at the same coordinate.
You will given M pieces of information regarding the positions of these people. The i-th piece of information has the form (Li,Ri,Di). This means that Person Ri is to the right of Person Li by Di units of distance, that is, xRi−xLi=Di holds.
It turns out that some of these M pieces of information may be incorrect. Determine if there exists a set of values (x1,x2,…,xN) that is consistent with the given pieces of information.
1≤N≤100000 1 ≤ N ≤ 100 000
0≤M≤200000 0 ≤ M ≤ 200 000
1≤Li,Ri≤N(1≤i≤M) 1 ≤ L i , R i ≤ N ( 1 ≤ i ≤ M )
0≤Di≤10000(1≤i≤M) 0 ≤ D i ≤ 10 000 ( 1 ≤ i ≤ M )
Li≠Ri(1≤i≤M) L i ≠ R i ( 1 ≤ i ≤ M )
If i≠j, then (Li,Ri)≠(Lj,Rj) and (Li,Ri)≠(Rj,Lj).
Di are integers.
Input is given from Standard Input in the following format:
N M
L1 R1 D1
L2 R2 D2
:
LM RM DM
If there exists a set of values (x1,x2,…,xN) that is consistent with all given pieces of information, print Yes; if it does not exist, print No.
3 3
1 2 1
2 3 1
1 3 2
Yes
Some possible sets of values (x1,x2,x3) are (0,1,2) and (101,102,103).
3 3
1 2 1
2 3 1
1 3 5
No
If the first two pieces of information are correct, x3−x1=2 holds, which is contradictory to the last piece of information.
4 3
2 1 1
2 3 5
3 4 2
Yes
10 3
8 7 100
7 9 100
9 8 100
No
100 0
Yes
(由作者本人提供,非官方!若有错误请谅解!O(∩_∩)O谢谢)
有 N 个人在x轴上,分别编号为1~N。现给出M组两人的关系,格式如下:
A B L
表示A与B的距离为L(保证A在B左边)。请判断——给出的关系是否可以全部成立,是则输出”Yes”,否则输出”No”。
1)可以把每一条输入看作一个图的描述,用邻接表储存。且由于A、B左右确定,我们只要知道其中一个点的坐标,我们就一定可以求出另一个点的确切坐标;
2)由于数据中可能存在与其它点不存在关系的点,即不是一个连通图。那么我们可以把图分割——给每一个连通图分配不同的轴,使得不同的连通图互不影响;
3)对于每一个连通图,我们只需要知道每个点对于某一个固定点的相对位置——不妨设该连通图内第一个出现的点为该轴的原点(这样就会非常方便);
主要算法是基于连通图的深度优先搜索,图的储存方法是邻接表。
1)邻接表的实现:
作者用的是最基础(最好写)的邻接表储存方式——STL vector<>,由于它的大小是可以改变的,初始状态是空,所以我们可以开一个数组:
vector vec[100005];
vec[i]储存与 i 相邻的元素——Vector是一个结构体,包含与 i 相邻元素的编号以及距离。这样不会有任何空间的浪费!
2)可行性剪枝
用一个 bool 数组vis表示当前点是否已经计算(或定义)过,如果是,则判断关系是否满足,若不满足,设置bool变量ERROR为true,然后直接return,不再计算!
3)搜索
main()函数中枚举每一个点,若当前点没有访问过(vis[i]==false)就说明这个点属于另一个独立的连通图,就可以以当前点为0点,进入搜索函数。
搜索函数内枚举与其邻接的每一个点,拓展搜索范围。若ERROR==true,则结束所有搜索(包括main()的循环枚举)。
答案是——真的不会(除非你代码写的丑)。很多人一听到暴力搜索就觉得一定会超时…实际上,只要剪枝,一切都好!
对于本题的算法,每个点只会访问一次,因此是接近于 O(n) O ( n ) 的时间复杂度,是显然可以的。
下面附上作者 Gitee 上的代码:
#2018/01/30# ★AtCoder Beginner★ People on a Line