https://vjudge.net/problem/Aizu-2224
场景嵌入得很好,如果不是再最小生成树专题里,我可能就想不到解法了。
对所有的边(栅栏)求最大生成树,剩下来的长度即解(也就是需要破环的最小边和)。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #define lson l, m, rt<<1 9 #define rson m+1, r, rt<<1|1 10 #define IO ios::sync_with_stdio(false);cin.tie(0); 11 #define INF 0x3f3f3f3f 12 typedef unsigned long long ll; 13 using namespace std; 14 int pre[100010]; 15 typedef struct{ 16 int x, y; 17 double w; 18 }Node; 19 Node node[100010]; 20 double length(int a, int b) 21 { 22 return sqrt(a*a+b*b); 23 } 24 bool cmp(const Node a, const Node b) 25 { 26 return a.w>b.w; 27 } 28 int find(int x) 29 { 30 while(x != pre[x]) 31 x = pre[x]; 32 return x; 33 } 34 int main() 35 { 36 int n, m, a[100010], b[100010], s, t; 37 while(cin >> n >> m){ 38 for(int i = 1; i <= n; i++){ 39 pre[i] = i; 40 } 41 double ans = 0, sum=0; 42 for(int i = 1; i <= n; i++){ 43 cin >> a[i] >> b[i]; 44 } 45 for(int i = 0; i < m; i++){ 46 cin >> s >> t; 47 double tmp = length(a[s]-a[t], b[s]-b[t]); 48 node[i].x = s; node[i].y = t; 49 node[i].w = tmp; 50 sum+=tmp; 51 } 52 sort(node, node+m, cmp); 53 for(int i = 0; i < m; i++){ 54 int tx = find(node[i].x); 55 int ty = find(node[i].y); 56 if(tx != ty){ 57 pre[tx] = ty; 58 ans += node[i].w; 59 } 60 } 61 printf("%.3lf ", sum-ans); 62 } 63 return 0; 64 }