結果
問題 | No.1983 [Cherry 4th Tune C] 南の島のマーメイド |
ユーザー | 草苺奶昔 |
提出日時 | 2023-12-24 02:03:08 |
言語 | Go (1.22.1) |
結果 |
AC
|
実行時間 | 547 ms / 4,000 ms |
コード長 | 4,571 bytes |
コンパイル時間 | 14,455 ms |
コンパイル使用メモリ | 229,260 KB |
実行使用メモリ | 127,488 KB |
最終ジャッジ日時 | 2024-09-27 13:33:46 |
合計ジャッジ時間 | 28,400 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 1 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
6,944 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 1 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 1 ms
5,376 KB |
testcase_08 | AC | 9 ms
5,376 KB |
testcase_09 | AC | 13 ms
5,376 KB |
testcase_10 | AC | 22 ms
5,760 KB |
testcase_11 | AC | 24 ms
5,376 KB |
testcase_12 | AC | 12 ms
5,376 KB |
testcase_13 | AC | 310 ms
22,400 KB |
testcase_14 | AC | 360 ms
34,048 KB |
testcase_15 | AC | 304 ms
26,368 KB |
testcase_16 | AC | 147 ms
19,584 KB |
testcase_17 | AC | 334 ms
37,120 KB |
testcase_18 | AC | 247 ms
24,704 KB |
testcase_19 | AC | 349 ms
41,216 KB |
testcase_20 | AC | 269 ms
24,064 KB |
testcase_21 | AC | 323 ms
35,200 KB |
testcase_22 | AC | 464 ms
54,016 KB |
testcase_23 | AC | 518 ms
56,448 KB |
testcase_24 | AC | 512 ms
56,448 KB |
testcase_25 | AC | 526 ms
56,064 KB |
testcase_26 | AC | 497 ms
55,936 KB |
testcase_27 | AC | 499 ms
55,936 KB |
testcase_28 | AC | 494 ms
55,936 KB |
testcase_29 | AC | 508 ms
56,448 KB |
testcase_30 | AC | 547 ms
56,064 KB |
testcase_31 | AC | 506 ms
56,448 KB |
testcase_32 | AC | 528 ms
56,448 KB |
testcase_33 | AC | 1 ms
5,376 KB |
testcase_34 | AC | 204 ms
10,416 KB |
testcase_35 | AC | 510 ms
127,488 KB |
testcase_36 | AC | 394 ms
28,732 KB |
testcase_37 | AC | 1 ms
5,376 KB |
testcase_38 | AC | 114 ms
5,376 KB |
testcase_39 | AC | 504 ms
126,976 KB |
testcase_40 | AC | 388 ms
33,792 KB |
ソースコード
package main import ( "bufio" "fmt" "os" "strings" ) func main() { Yuki1983() // yosupo() } func Yuki1983() { // https://yukicoder.me/problems/no/1983 // 给定一个无向图 // 对每个查询a,b,问从a到b的路径是否存在且唯一 // !用并查集把所有的桥的端点合并 // !如果起点终点在一个连通分量内,那么答案就是Yes(只能通过桥往来) in := bufio.NewReader(os.Stdin) out := bufio.NewWriter(os.Stdout) defer out.Flush() var n, m, q int fmt.Fscan(in, &n, &m, &q) graph := make([][]Neighbor, n) edges := make([][2]int, 0, m) for i := 0; i < m; i++ { var u, v int fmt.Fscan(in, &u, &v) u, v = u-1, v-1 edges = append(edges, [2]int{u, v}) graph[u] = append(graph[u], Neighbor{to: v, id: i}) graph[v] = append(graph[v], Neighbor{to: u, id: i}) } _, belong := TwoEdgeComponent(n, m, graph) uf := NewUnionFindArray(n) for _, e := range edges { u, v := e[0], e[1] if belong[u] != belong[v] { // (u,v)是桥 uf.Union(u, v) } } for i := 0; i < q; i++ { var a, b int fmt.Fscan(in, &a, &b) a, b = a-1, b-1 if uf.IsConnected(a, b) { fmt.Fprintln(out, "Yes") } else { fmt.Fprintln(out, "No") } } } // https://judge.yosupo.jp/problem/two_edge_connected_components func yosupo() { in := bufio.NewReader(os.Stdin) out := bufio.NewWriter(os.Stdout) defer out.Flush() var n, m int fmt.Fscan(in, &n, &m) g := make([][]Neighbor, n) for i := 0; i < m; i++ { var u, v int fmt.Fscan(in, &u, &v) g[u] = append(g[u], Neighbor{v, i}) g[v] = append(g[v], Neighbor{u, i}) } count, belong := TwoEdgeComponent(n, m, g) group := make([][]int, count) for i := 0; i < n; i++ { group[belong[i]] = append(group[belong[i]], i) } fmt.Fprintln(out, count) for _, p := range group { fmt.Fprint(out, len(p)) for _, v := range p { fmt.Fprint(out, " ", v) } fmt.Fprintln(out) } } type Neighbor = struct{ to, id int } // 求无向图的边双连通分量. // 返回值为 (边双连通分量数, 每个点所属的边双连通分量编号). // !如果某条边(u,v)满足 `belong[u]!=belong[v]`,则称该边为桥. func TwoEdgeComponent(n, m int, graph [][]Neighbor) (count int, belong []int) { path := make([]int, 0, n) parent := make([]int, n) for i := range parent { parent[i] = -2 } dp := make([]int, n) belong = make([]int, n) used := make([]bool, m) var dfs func(int) dfs = func(v int) { path = append(path, v) for _, e := range graph[v] { if used[e.id] { continue } used[e.id] = true if parent[e.to] == -2 { parent[e.to] = v dfs(e.to) } else { dp[v]++ dp[e.to]-- } } } for v := 0; v < n; v++ { if parent[v] == -2 { parent[v] = -1 dfs(v) } } for i := n - 1; i >= 0; i-- { v := path[i] if parent[v] != -1 { dp[parent[v]] += dp[v] } } for _, v := range path { if dp[v] == 0 { belong[v] = count count++ } else { belong[v] = belong[parent[v]] } } return } // 边双缩点成树. // func ToDag(n, m int, graph [][]Neighbor) (dag [][]int) {} func NewUnionFindArray(n int) *_UnionFindArray { parent, rank := make([]int, n), make([]int, n) for i := 0; i < n; i++ { parent[i] = i rank[i] = 1 } return &_UnionFindArray{ Part: n, rank: rank, n: n, parent: parent, } } type _UnionFindArray struct { // 连通分量的个数 Part int rank []int n int parent []int } func (ufa *_UnionFindArray) Union(key1, key2 int) bool { root1, root2 := ufa.Find(key1), ufa.Find(key2) if root1 == root2 { return false } if ufa.rank[root1] > ufa.rank[root2] { root1, root2 = root2, root1 } ufa.parent[root1] = root2 ufa.rank[root2] += ufa.rank[root1] ufa.Part-- return true } func (ufa *_UnionFindArray) Find(key int) int { for ufa.parent[key] != key { ufa.parent[key] = ufa.parent[ufa.parent[key]] key = ufa.parent[key] } return key } func (ufa *_UnionFindArray) IsConnected(key1, key2 int) bool { return ufa.Find(key1) == ufa.Find(key2) } func (ufa *_UnionFindArray) GetGroups() map[int][]int { groups := make(map[int][]int) for i := 0; i < ufa.n; i++ { root := ufa.Find(i) groups[root] = append(groups[root], i) } return groups } func (ufa *_UnionFindArray) Size(key int) int { return ufa.rank[ufa.Find(key)] } func (ufa *_UnionFindArray) String() string { sb := []string{"UnionFindArray:"} for root, member := range ufa.GetGroups() { cur := fmt.Sprintf("%d: %v", root, member) sb = append(sb, cur) } sb = append(sb, fmt.Sprintf("Part: %d", ufa.Part)) return strings.Join(sb, "\n") }