给你一个动态最小生成树。
问:
这棵生成树,改变了几次。
注意好讨论
)#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define mst(x, a) memset(x,a,sizeof(x))
using namespace std;
const int maxn = 50 + 5;
const double eps = 1e-8;
struct point{
int x, y, z, dx, dy, dz;
} p[maxn];
struct EDGE{
int a, b, c;
int u, v;
bool operator< (const EDGE& x)const{
return c < x.c;
}
}edges[maxn*maxn];
struct EVENT{
double t;
int olde;
int newe;
bool operator < (const EVENT& x)const {
return t<x.t;
}
}event[2*maxn*maxn*maxn*maxn];
int mul(int i, int j) { return (i-j)*(i-j);}
int n;
int tot1 = 0, tot2 = 0;
void init(){
tot1 = 0, tot2 = 0;
int x, y, z, dx, dy, dz;
For(i,1,n){
cin>>x>>y>>z>>dx>>dy>>dz;
p[i]={x, y, z, dx, dy, dz};
}
}
void build(){
For(i,1,n){
For(j,i+1,n){
EDGE e;
e.a = mul(p[i].dx, p[j].dx) + mul(p[i].dy, p[j].dy) + mul(p[i].dz, p[j].dz);
e.b = 2 * ((p[i].x - p[j].x) * (p[i].dx - p[j].dx) + (p[i].y - p[j].y) * (p[i].dy - p[j].dy) + (p[i].z - p[j].z)*(p[i].dz - p[j].dz));
e.c = mul(p[i].x, p[j].x) + mul(p[i].y, p[j].y) + mul(p[i].z, p[j].z);
e.u = i; e.v = j;
edges[tot1++] = e;
}
}
sort(edges, edges + tot1);
fori(i,0,tot1){
fori(j,i+1,tot1){
int s1 = i, s2 = j;
int a = edges[i].a - edges[j].a;
int b = edges[i].b - edges[j].b;
int c = edges[i].c - edges[j].c;
if(a < 0) { a = -a; c = -c; b = -b; swap(s1,s2);}
if(a == 0){//fabs(a) < eps)
if(b == 0) continue;
if(b > 0) {b = -b; c = -c; swap(s1,s2);}//b>0, 同时取负.
if(c > 0) {double t = (double)c/(double)(-b); event[tot2++] = {t, s2, s1};}
continue;
}
double delta = b*b - 4*a*c;
if(fabs(delta) < 0)continue;
delta = sqrt(delta);
double t1 = (delta - b) / (double)(2*a);
double t2 = (-delta - b) / (double)(2*a);
if(t1>0)event[tot2++] = {t1, s1, s2};
if(t2>0)event[tot2++] = {t2, s2, s1};
}
}
sort(event, event+tot2);
}
int f[maxn], order[maxn];
int find(int x){
if(x == f[x])return x;
return f[x] = find(f[x]);
}
int solve(){
int ans = 1;
For(i,1,n)f[i] = i;
int u, v, a, b;
int cnt = 1;
int idx = 0;
mst(order,0);
fori(i,0,tot1){
u = edges[i].u; v = edges[i].v;
a = find(u), b =find(v);
if(a == b) continue;
f[a] = b;
cnt++;
order[idx++] = i;
if(cnt == n)break;
}
fori(i,0,tot2){
double t = event[i].t;
int newe = event[i].newe;
int olde = event[i].olde;
For(j,1,n)f[j] = j; cnt = 1;
int pos = 0, vis = false;
fori(j,0,idx)if(order[j] == newe) vis= true;
if(vis)continue;/// olde and newe isn't in a same set
fori(j,0,idx){
if(order[j] == olde){
pos = j;
continue;
}
u = edges[order[j]].u; v = edges[order[j]].v;
a = find(u); b = find(v);
if(a == b)continue;
f[a] = b;
cnt++;
if(cnt == n)break;
}
u = edges[newe].u; v = edges[newe].v;
a = find(u); b = find(v);
if(a != b && ++cnt == n){
order[pos] = newe;
ans++;
}
}
return ans;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int kase = 0;
while(cin>>n){
init();
build();
cout<<"Case "<<++kase<<": "<<solve()<<endl;
}
return 0;
}