D. The Child and Zoo 2
Posted towerbird
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. The Child and Zoo 2相关的知识,希望对你有一定的参考价值。
http://codeforces.com/contest/437/problem/D
排序+并查集
为了理解原理,让我们先画一个圈:
其中红边无限大,黑边值为0
我们可以发现,红边的值:1、直接就是f(1,2),2、毫不影响剩下的f(1,3)、f(1,4)、f(2,3)、f(2,4)、f(3,4)的值
所以对应的,我们可以得出:1、当它是图里最大的边时,它的贡献可求,2、球完之后,它唯一的作用就是确保连通性,除此之外就是个摆设
而题目里求所有点对的f()值等价于求所有边对所有点对的贡献
解决1用排序,解决2用并查集
1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 import static java.lang.Math.min; 5 6 public class Main 7 static final int MAX = Integer.MAX_VALUE; 8 static int[] f = new int[100000 + 50]; 9 10 public static void main(String[] args) 11 Scanner io = new Scanner(System.in); 12 int n = io.nextInt(), m = io.nextInt(); 13 14 int[] a = new int[n + 1], c = new int[n + 1]; 15 for (int i = 1; i <= n; i++) 16 a[i] = io.nextInt(); 17 f[i] = i; 18 c[i] = 1; 19 20 21 P[] ps = new P[m]; 22 for (int i = 0, aa, bb; i < m; i++) 23 aa = io.nextInt(); 24 bb = io.nextInt(); 25 ps[i] = new P(aa, bb, min(a[aa], a[bb])); 26 27 28 Arrays.sort(ps); 29 double w = 0; 30 for (int i = 0, fx, fy, v; i < m; i++) 31 P p = ps[i]; 32 fx = find(p.x); 33 fy = find(p.y); 34 v = p.v; 35 if (fx == fy) continue; 36 //这道题这里和下面非常容易溢出,升double是必须的 37 // 并且1L和1.0【一定】要放在最前面,因为它是一边乘一边检测 38 // 什么时候碰到1.0就什么时候升double 39 w += 1L * v * c[fx] * c[fy]; 40 f[fx] = fy; 41 c[fy] += c[fx]; 42 43 //下面 44 System.out.println(w / (1.0 * n * (n - 1) / 2)); 45 46 47 static int find(int x) 48 return f[x] == x ? x : (f[x] = find(f[x])); 49 50 51 static class P implements Comparable<P> 52 int x, y, v; 53 54 public P(int x, int y, int v) 55 this.x = x; 56 this.y = y; 57 this.v = v; 58 59 60 @Override 61 public int compareTo(P o) 62 return -v + o.v; 63 64 65
以上是关于D. The Child and Zoo 2的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 437 D. The Child and Zoo 并查集
Codeforces 437D The Child and Zoo
[线段树 区间取模] D. The Child and Sequence
Codeforces Round #250 (Div. 1) - D. The Child and Sequence(线段树)