PTA 分而治之 Java
分而治之,各個擊破是兵家常用的策略之一。在戰爭中,我們希望首先攻下敵方的部分城市,使其剩餘的城市變成孤立無援,然後再分頭各個擊破。爲此參謀部提供了若干打擊方案。本題就請你編寫程序,判斷每個方案的可行性。
輸入格式:
輸入在第一行給出兩個正整數 N 和 M(均不超過10 000),分別爲敵方城市個數(於是默認城市從 1 到 N 編號)和連接兩城市的通路條數。隨後 M 行,每行給出一條通路所連接的兩個城市的編號,其間以一個空格分隔。在城市信息之後給出參謀部的系列方案,即一個正整數 K (≤ 100)和隨後的 K 行方案,每行按以下格式給出:
Np v[1] v[2] … v[Np]
其中 Np 是該方案中計劃攻下的城市數量,後面的系列 v[i] 是計劃攻下的城市編號。
輸出格式:
對每一套方案,如果可行就輸出YES,否則輸出NO。
輸入樣例:
10 11
8 7
6 8
4 5
8 4
8 1
1 2
1 4
9 8
9 1
1 10
2 4
5
4 10 3 8 4
6 6 1 7 5 4 9
3 1 8 4
2 2 8
7 9 8 7 6 5 4 2
輸出樣例:
NO
YES
YES
NO
NO
乍一看,並查集,判斷連通數是否等於剩餘城市數
仔細一想,所有的路都走不通了不就是所有城市都被孤立了嗎…
可惜最後一個測試用例超時…
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
Reader.init(System.in);
int N = Reader.nextInt();
int M = Reader.nextInt();
// 讀取數據
linked_list[] path = new linked_list[N + 1]; // 記錄有路通向外面的城市
for (int i = 1; i < path.length; i++) {
path[i] = new linked_list();
}
for (int i = 0; i < M; i++) {
int s = Reader.nextInt();
int e = Reader.nextInt();
path[s].list.add(e); // 只需要記錄一個方向即可
path[s].exits = path[e].exits = 1; // 標記是有路的城市
}
int K = Reader.nextInt();
for (int i = 0; i < K; i++) {
// 讀取攻打計劃
int Np = Reader.nextInt();
int[] plan = new int[N + 1]; // 記錄要攻打的城市
for (int j = 0; j < Np; j++) {
plan[Reader.nextInt()] = 1;
}
boolean isOK = true; // 判斷是否可行
for (int j = 1; j < path.length && isOK; j++) {
// 如果該城市不是本來就孤立,且不在攻打的計劃上
if (path[j].exits == 1 && plan[j] != 1) {
// 那麼查找是否有城市和該城市相連接
for (int item : path[j].list) {
// 如果找到了一個不在攻打計劃上的城市和該城市相連,則表示計劃不可行
if (plan[item] != 1) {
isOK = false;
break;
}
}
}
}
if (isOK) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
static class linked_list {
int exits = 0;
LinkedList<Integer> list = new LinkedList<Integer>();
}
}
// Class for buffered reading int and double values *//*
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
// ** call this method to initialize reader for InputStream *//*
static void init(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
static void init(File file) {
try {
reader = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tokenizer = new StringTokenizer("");
}
// ** get next word *//*
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
// TODO add check for eof if necessary
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static String nextLine() throws IOException {
return reader.readLine();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
static char nextChar() throws IOException {
return next().toCharArray()[0];
}
static float nextFloat() throws IOException {
return Float.parseFloat(next());
}
static Double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}