結果

問題 No.416 旅行会社
ユーザー GrenacheGrenache
提出日時 2016-08-28 17:15:20
言語 Java21
(openjdk 21)
結果
AC  
実行時間 1,392 ms / 4,000 ms
コード長 5,120 bytes
コンパイル時間 4,522 ms
コンパイル使用メモリ 80,724 KB
実行使用メモリ 82,560 KB
最終ジャッジ日時 2024-05-08 15:19:44
合計ジャッジ時間 20,663 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 849 ms
77,292 KB
testcase_01 AC 57 ms
37,404 KB
testcase_02 AC 57 ms
37,376 KB
testcase_03 AC 58 ms
37,532 KB
testcase_04 AC 57 ms
37,528 KB
testcase_05 AC 59 ms
37,692 KB
testcase_06 AC 59 ms
37,672 KB
testcase_07 AC 89 ms
38,456 KB
testcase_08 AC 137 ms
40,704 KB
testcase_09 AC 208 ms
44,964 KB
testcase_10 AC 1,005 ms
77,512 KB
testcase_11 AC 1,030 ms
77,408 KB
testcase_12 AC 968 ms
78,984 KB
testcase_13 AC 813 ms
74,856 KB
testcase_14 AC 1,333 ms
78,988 KB
testcase_15 AC 1,357 ms
82,560 KB
testcase_16 AC 1,367 ms
76,552 KB
testcase_17 AC 1,392 ms
79,844 KB
testcase_18 AC 1,301 ms
76,428 KB
testcase_19 AC 1,035 ms
81,160 KB
testcase_20 AC 1,023 ms
79,448 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import java.io.*;
import java.util.*;


public class Main_yukicoder416_1 {

    public static void main(String[] args) {
    	Scanner sc = new Scanner(System.in);
    	Printer pr = new Printer(System.out);

		int n = sc.nextInt();
		int m = sc.nextInt();
		int q = sc.nextInt();

		Set<Long> hs = new HashSet<>();
		for (int i = 0; i < m; i++) {
			int a = sc.nextInt() - 1;
			int b = sc.nextInt() - 1;

			hs.add((long)a << 32 | b);
		}

		int[] c = new int[q];
		int[] d = new int[q];
		for (int i = 0; i < q; i++) {
			c[i] = sc.nextInt() - 1;
			d[i] = sc.nextInt() - 1;

			hs.remove((long)c[i] << 32 | d[i]);
		}

		UnionFindList uf = new UnionFindList(n);
		int[] ret = new int[n];
		Arrays.fill(ret, -1);

		for (long e : hs) {
			int a = (int)(e >> 32);
			int b = (int)(e & 0xffff_ffff);

			uf.unite(a, b);
		}

		for (int i = q - 1; i >= 0; i--) {
			if(uf.same(c[i], d[i])) {
				continue;
			}

			if (uf.same(0, c[i])) {
				for (int e : uf.getList(d[i])) {
					ret[e] = i + 1;
				}
			} else if (uf.same(0, d[i])) {
				for (int e : uf.getList(c[i])) {
					ret[e] = i + 1;
				}
			}
			uf.unite(c[i], d[i]);
		}

		for (int i = 1; i < n; i++) {
			if (ret[i] == -1 && !uf.same(0, i)) {
				pr.println(0);
			} else {
				pr.println(ret[i]);
			}
		}

    	pr.close();
        sc.close();
    }

	@SuppressWarnings("unused")
	private static class UnionFindList {
		int n;
		// cnt : 異なる集合の数
		int cnt;

		// i2g : i番目の要素が属するグループ
		List<Integer> i2g;
		// g2i : そのグループに属する要素のリスト
		List<List<Integer>> g2i;

		UnionFindList(int n) {
			this.n = n;
			cnt = n;
			i2g = new ArrayList<>(n);
			g2i = new ArrayList<>(n);
			for (int i = 0; i < n; i++) {
				i2g.add(i);
				List<Integer> tmp = new ArrayList<>();
				tmp.add(i);
				g2i.add(tmp);
			}
		}

		// xのrootを求める
		int find(int x) {
			return i2g.get(x);
		}

		// xとyが同じ集合に属するのか
		boolean same(int x, int y) {
			return find(x) == find(y);
		}

		// xとyの属する集合を併合する
		void unite(int x, int y) {
			x = find(x);
			y = find(y);
			if (x == y) {
				return;
			}

			cnt--;
			// 要素数が大きい集合にmergeする(Quick Find Weighted?)
			if (g2i.get(x).size() > g2i.get(y).size()) {
				g2i.get(x).addAll(g2i.get(y));
				for (int e : g2i.get(y)) {
					i2g.set(e, x);
				}
				g2i.set(y, null);
			} else {
				g2i.get(y).addAll(g2i.get(x));
				for (int e : g2i.get(x)) {
					i2g.set(e, y);
				}
				g2i.set(x, null);
			}

			return;
		}

		public List<Integer> getList(int x) {
			return g2i.get(find(x));
		}

		// 要素xを含む集合の要素数
		int count(int x) {
			return g2i.get(find(x)).size();
		}

		// 異なる集合の数
		int count() {
			return cnt;
		}
	}

	@SuppressWarnings("unused")
	private static class Scanner {
		BufferedReader br;

		Scanner (InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		private boolean isPrintable(int ch) {
			return ch >= '!' && ch <= '~';
		}

		private boolean isCRLF(int ch) {
			return ch == '\n' || ch == '\r';
		}

		private int nextPrintable() {
			try {
				int ch;
				while ((ch = br.read()) != -1 && !isPrintable(ch)) {
				}
				return ch;
			} catch (IOException e) {
				throw new IllegalStateException();
			}
		}

		String next() {
			try {
				int ch = nextPrintable();
				StringBuilder sb = new StringBuilder();
				while (isPrintable(ch)) {
					sb.appendCodePoint(ch);
					ch = br.read();
				}

				return sb.toString();
			} catch (IOException e) {
				throw new IllegalStateException();
			}
		}

		int nextInt() throws RuntimeException {
			try {
				// parseInt
				boolean negative = false;
				int res = 0;

				int fc = nextPrintable();
				if (fc < '0') {
					if (fc == '-') {
						negative = true;
					} else if (fc != '+') {
						throw new NumberFormatException();
					}
					fc = br.read();
				}

				int ch = fc;
				do {
					if (ch < '0' || ch > '9') {
						throw new NumberFormatException();
					}

					res *= 10;
					res += ch - '0';
				} while ((ch = br.read()) != -1 && isPrintable(ch));

				// parseInt

				return negative ? -res : res;
			} catch (IOException e) {
				throw new IllegalStateException();
			}
		}

		long nextLong() throws RuntimeException {
			return Long.parseLong(next());
		}

		float nextFloat() throws RuntimeException {
			return Float.parseFloat(next());
		}

		double nextDouble() throws RuntimeException {
			return Double.parseDouble(next());
		}

		String nextLine() throws RuntimeException {
			try {
				int ch;
				while ((ch = br.read()) != -1 && !isCRLF(ch)) {
				}
				StringBuilder sb = new StringBuilder();
				while (!isCRLF(ch)) {
					sb.appendCodePoint(ch);
					ch = br.read();
				}

				return sb.toString();
			} catch (IOException e) {
				throw new IllegalStateException();
			}
		}

		void close() {
			try {
				br.close();
			} catch (IOException e) {
//				throw new IllegalStateException();
			}
		}
	}

	private static class Printer extends PrintWriter {
		Printer(PrintStream out) {
			super(out);
		}
	}
}
0