AZNET - VOI 2014 - Mang truyen thong

Tags: kruskal, dsu, mst, graph

Problem

https://vn.spoj.com/problems/AZNET

https://oj.vnoi.info/problem/AZNET

Ngân hàng AZ có n chi nhánh, mỗi chi nhánh có một máy chủ là đầu mối đảm bảo truyền thông với các chi nhánh còn lại. Các máy chủ ở các chi nhánh được đánh số từ 1 đến n. Để đảm bảo truyền thông giữa các chi nhánh, ngân hàng thuê m kênh truyền tin của hai công ty A và B để kết nối n máy chủ của các chi nhánh thành một mạng máy tính. Các kênh truyền tin được đánh số từ 1 đến m, không có hai kênh truyền tin nào kết nối cùng một cặp máy chủ. Kênh truyền tin i (thuê của công ty A hoặc B) đảm bảo việc truyền tin hai chiều giữa máy chủ của chi nhánh ui và vi (i = 1, 2, …, m). Mạng máy tính có tính chất thông suốt nghĩa là đảm bảo từ máy chủ của một chi nhánh bất kỳ có thể truyền tin đến tất cả các máy chủ của các chi nhánh còn lại theo kênh truyền tin trực tiếp giữa chúng hoặc thông qua đường truyền đi qua một số máy chủ của các chi nhánh nào đó. Trong thời gian tới do tình hình tài chính gặp khó khăn, ngân hàng muốn cắt giảm tối đa việc thuê các kênh truyền tin nhưng vẫn đảm bảo mạng thông suốt. Do chi phí thuê bao phụ thuộc vào số lượng kênh truyền tin phải thuê, nêu sau khi hỏi ý kiến các chuyên gia, ngân hàng được biết là để đảm bảo tính thông suốt của mạng, tối thiểu phải thuê n - 1 kênh truyền tin. Từ bảng đơn giá thuê bao kênh truyền tin với hai công ty ta biết ak và bk tương ứng là giá thuê bao k kênh truyền tin của công ty A và B (k = 1, 2, …, n - 1). Ngân hàng muốn tìm phương án giữ lại đúng n - 1 kênh truyền tin trong số m kênh truyền tin đã thuê của hai công ty sao cho tổng chi phí thuê bao phải trả là nhỏ nhất mà vẫn đảm bảo tính thông suốt của mạng.

Yêu cầu

Cho biết danh sách các kênh truyền tin và các chi phí ak, bk (k = 1, 2, …, n - 1). Hãy tìm phương án giữ lại đúng n - 1 kênh truyền tin trong số m kênh truyền tin đã thuê của hai công ty sao cho tổng chi phí thuê bao phải trả là nhỏ nhất mà vẫn đảm bảo tính thông suốt của mạng.

Input

Dòng đầu tiên chứa T là số lượng bộ dữ liệu. Tiếp đến là T nhóm dòng, mỗi nhóm dòng cho biết thông tin về một bộ dữ liệu theo khuôn dạng sau:

  • Dòng thứ nhất chứa hai số nguyên dương n, m;
  • Dòng thứ hai chứa n - 1 số nguyên dương a1, a2, …, a(n - 1) mỗi số nhỏ hơn 10^9.
  • Dòng thứ bai chứa n - 1 sô nguyên dương b1, b2, …, b(n - 1) mỗi số nhỏ hơn 10^9.
  • Dòng thứ i trong số m dòng tiếp theo chứa ba số nguyên dương ui, vi, ci cho biết thông tin về kênh truyền tin thứ i (i = 1, 2, …, m). Giả thiết ui khác vi, ci = 1 nếu kênh truyền tin thuê của công ty A, ci = 2 nếu kênh truyền tin thuê của công ty B.

Giải thích

  • 30% số test có n < 10.
  • 30% số test khác có n < 100.
  • 40% số test còn lại có n <= 10^4, m <= 10^5.

Output

  • Ghi ra T dòng mỗi dòng ghi kết quả của bộ test tương ứng: chỉ số những cạnh được giữ lại.
  • Nếu có nhiều cách thì in ra cách bất kì.

Example

Input
1
3 3
1 2
1 5
1 2 1
1 3 2
2 3 2

Output
1 3

Tutorial

Bài toán cho N đỉnh, M cạnh, mỗi cạnh thuộc 1 trong 2 loại AB. Mỗi cạnh không có trọng số. Cần tìm ra cây khung trong đồ thị sao cho chi phí thấp nhất. Chi phí của cây khung được tính bằng số lượng cạnh loại A và loại B trong cây khung tìm được. Giả sử chọn ra x cạnh loại Ay cạnh loại B thì chi phí là A[x] + B[y], trong đó 2 mảng A[1..n-1]B[1..n-1] đã được cho.

Nhận xét: bài này là bài toán khó. Trước hết tính số lượng các cạnh loại A tối đa có thể hợp nhất trong quá trình tạo cây khung thông thường. Gọi số luợng cạnh tìm được là biến A. Làm tương tự như vậy cho các cạnh loại B.

Khi đó ta cần chọn ra x cạnh loại Ay = n-1-x cạnh loại B. Đồng thời giá trị a[x] + b[y] min.

Ta có 0 <= x <= A0 <= y <= B hay 0 <= n-1-x <= B

Do đó: Max(0, n-1-B) <= x <= Min(A, n-1).

Từ đó ta duyệt tìm giá trị x sao cho a[x] + b[n-1-x] min.

Lúc này ta đã xác định được giá trị x cũng như y = n-1-x. Công đoạn tiếp theo, khi ta đã hợp nhất B cạnh loại B rồi, ta sẽ hợp nhất các cạnh loại A trong quá trình tạo cây khung, khi đó thì những cạnh loại A được chọn này (gọi số lượng này là biến cnt) là những cạnh bắt buộc phải có trong cây khung, vì nếu không thì không thể tạo được cây khung nữa. Sau đó, ta xóa toàn bộ cây khung đó đi, bắt đầu tìm lại cây khung với một cây mới.

Với cây khung mới, ta hợp nhất cnt cạnh A vừa tìm được ở bước trên, sau đó hợp thêm x-cnt cạnh loại A nữa để đủ x cạnh A, sau đó hợp nhất thêm n-1-x cạnh B nữa thì sẽ được cây khung cần tìm.


Submission

AZNET.cpp