第一行输入两个正整数
,代表城市数量和道路数量。
第二行输入一个长度为
的 01 串。第
个字符为 '0' 代表小欧未占领该城市,'1' 代表小欧已经占领了该城市。
接下来的
行,每行输入两个正整数
,代表城市
和城市
有一条道路连接。
输出一行两个空格隔开的整数,第一个整数代表占领的城市编号,第二个整数代表占领后的收益。
请保证收益的最大化。如果有多种方案收益最大,小欧会优先占领编号最小的城市。
5 5 01010 1 2 1 3 1 4 4 5 1 5
1 3
占领 1 号城市后,总收益为 3。1 号城市和 2 号城市经商,1 号城市和 4 号城市经商,2 号城市和 4 号城市经商。
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int[] fa, size;
static int find(int x) {
return x == fa[x] ? x : (fa[x] = find(fa[x]));
}
static void union(int x, int y) {
int fx = find(x), fy = find(y);
if (fx == fy) return;
if (size[fx] < size[fy]) {
size[fy] += size[fx];
fa[fx] = fy;
} else {
size[fx] += size[fy];
fa[fy] = fx;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt();
sc.nextLine();
fa = new int[n + 1];
size = new int[n + 1];
for (int i = 1; i <= n; i++) {
fa[i] = i;
size[i] = 1;
}
String occ = sc.nextLine();
char[] chs = occ.toCharArray();
List<Integer>[] G = new ArrayList[n + 1];
for (int i = 1; i <= n; i++) G[i] = new ArrayList<>();
for (int i = 0; i < m; i++) {
int u = sc.nextInt(), v = sc.nextInt();
G[u].add(v);
G[v].add(u);
if (chs[u - 1] == '1' && chs[v - 1] == '1') union(v, u);
}
long ans = 0;
boolean[] used = new boolean[n + 1];
for (int u = 1; u <= n; u++) {
int f = find(u);
if (used[f]) continue;
used[f] = true;
ans += (long) size[f] * (size[f] - 1) / 2;
}
// System.out.println(ans);
long maxProfit = 0;
int idx = -1;
Arrays.fill(used, false);
for (int u = 1; u <= n; u++) {
if (chs[u - 1] == '0') {
long curProfit = 0, pref = 1;
for (int v : G[u]) {
int f = find(v);
if (chs[v - 1] == '0' || used[f]) continue;
used[f] = true;
curProfit += pref * size[f];
pref += size[f];
}
for (int v : G[u]) {
int f = find(v);
if (chs[v - 1] == '0' || !used[f]) continue;
used[f] = false;
}
if (curProfit > maxProfit) {
maxProfit = curProfit;
idx = u;
}
}
}
System.out.println(idx + " " + (ans + maxProfit));
}
}