AtCoder Beginner Contest 238 E - E - Range Sums(建图)

E - Range Sums

题目大意:

给定一些区间的和,判断是否可以在其中选择一些区间,使得可以通过这些区间的和算出 1 到 \(n\) 的区间和。

思路:

考虑将 \(a_i\) 看成点,对于 \([l, r]\) 的区间和,相当于建一条 \(l-1\)\(r\) 的边。那么要想算出 1 到 \(n\) 的区间和,就看能不能从 0 经过一条路径到达 \(n\)

如何理解这样的建图?

看样例1

Sample Input 1
3 3
1 2
2 3
2 2

Sample Output 1
Yes

From the first and second information, we can find the value \(a_1 + a_2 + a_2 + a_3\) . By subtracting the value of \(a_2\) from it, we can determine the value \(a_1 + a_2 + a_3\) .

这里提到的减去区间的和,在图上相当于抵消掉重叠的边。

zzz

Code:
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n, q int
	fmt.Fscan(in, &n, &q)
	g := make([][]int, n+1)
	for i := 0; i < q; i++ {
		var l, r int
		fmt.Fscan(in, &l, &r)
		g[l-1] = append(g[l-1], r)
		g[r] = append(g[r], l-1)
	}

	vis := make([]bool, n+1)
	ok := false
	var dfs func(u, fa int)
	dfs = func(u, fa int) {
		if u == n || ok {
			ok = true
			return
		}
		if vis[u] {
			return
		}
		vis[u] = true
		for _, v := range g[u] {
			if v != fa {
				dfs(v, u)
			}
		}
	}

	dfs(0, -1)

	if ok {
		fmt.Fprintln(out, "Yes")
	} else {
		fmt.Fprintln(out, "No")
	}
}
posted @ 2022-03-15 11:02  Nepenthe8  阅读(102)  评论(0编辑  收藏  举报