【搜索算法】 ★AtCoder网络赛★ People on a line

★AtCoder 网络赛★

D-People on a line


◆谈一谈感想…◆

第一次网络赛…(继NOIP 2017 之后的第一场竞赛),参加了Beginner(初学者)比赛。感觉不错,好像是第 24 名,也算是给祖国涨了脸吧 <( ̄ˇ ̄)/。
那么D题(最后一题),其实我还有50分钟的时间…于是我就…想了30分钟 (oh!),想了很多种方法,像并查集、动态规划什么的都想过,只是确实能力有限,写不了并查集(动态规划被我否认了),误打误撞,我决定暴力一下 —— 于是我加了一点可行性剪枝。然而这是官方标程!!!


◆题目◆

Time limit : 2sec / Memory limit : 256MB
Score : 400 points

Problem Statement

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.

Constraints

1N100000 1 ≤ N ≤ 100 000
0M200000 0 ≤ M ≤ 200 000
1Li,RiN(1iM) 1 ≤ L i , R i ≤ N ( 1 ≤ i ≤ M )
0Di10000(1iM) 0 ≤ D i ≤ 10 000 ( 1 ≤ i ≤ M )
LiRi(1iM) L i ≠ R i ( 1 ≤ i ≤ M )
If i≠j, then (Li,Ri)≠(Lj,Rj) and (Li,Ri)≠(Rj,Lj).
Di are integers.

Input

Input is given from Standard Input in the following format:

N M
L1 R1 D1
L2 R2 D2
:
LM RM DM

Output

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.

Sample Input 1

3 3
1 2 1
2 3 1
1 3 2

Sample Output 1

Yes

Some possible sets of values (x1,x2,x3) are (0,1,2) and (101,102,103).

Sample Input 2

3 3
1 2 1
2 3 1
1 3 5

Sample Output 2

No

If the first two pieces of information are correct, x3−x1=2 holds, which is contradictory to the last piece of information.

Sample Input 3

4 3
2 1 1
2 3 5
3 4 2

Sample Output 3

Yes

Sample Input 4

10 3
8 7 100
7 9 100
9 8 100

Sample Output 4

No

Sample Input 5

100 0

Sample Output 5

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

你可能感兴趣的:(#搜索算法,-,暴力出奇迹#)