P7862 [COCI2015-2016#2] DRŽAVA 题解
题意
给定一个
题解
乱搞过的,但实际上复杂度可以做到保证。
首先有一个结论:一个大小为
那么意味着,对于一个点找周围最近的
怎么找最近
#include<bits/stdc++.h>
// #define ONLINE_JUDGE
#define INPUT_DATA_TYPE int
#define OUTPUT_DATA_TYPE int
inline __attribute((always_inline)) INPUT_DATA_TYPE read(){register INPUT_DATA_TYPE x=0;register char f=0,c=getchar();while(c<'0'||'9'<c)f=(c=='-'),c=getchar();while('0'<=c&&c<='9')x=(x<<3)+(x<<1)+(c&15),c=getchar();return f?-x:x;}void print(OUTPUT_DATA_TYPE x){if(x<0)x=-x,putchar('-');if(x>9)print(x/10);putchar(x%10^48);return;}
struct NODE{
int x,y,val;
}nods[50010];
struct EDGE{
int x,y;
double dis;
bool operator < (const EDGE o) const{
return dis<o.dis;
}
};
std::vector<EDGE> edges;
int par[50010];
char f[50010][40],g[70];
int find(int x){return (x==par[x])?x:(par[x]=find(par[x]));}
double dis(int x,int y){
return sqrt(1ll*(nods[x].x-nods[y].x)*(nods[x].x-nods[y].x)+1ll*(nods[x].y-nods[y].y)*(nods[x].y-nods[y].y));
}
int main(){
#ifndef ONLINE_JUDGE
freopen("name.in", "r", stdin);
freopen("name.out", "w", stdout);
#endif
register int i,j,l,r,pari,parj;
int n=read();int k=read();
for(i=1;i<=n;++i){
//要卡就这样输入 能卡掉几篇题解
// nods[i].x=1;
// nods[i].y=1e8/n*i;
// nods[i].val=0;
nods[i].x=read();
nods[i].y=read();
nods[i].val=read()%k;
}
std::sort(nods+1,nods+1+n,[](auto a,auto b){return a.x==b.x?a.y<b.y:a.x<b.x;});
for(i=1;i<=n;++i){
std::priority_queue<std::pair<double,int>> h;
for(j=i+1;j<=n;++j){
if(h.size()<k) h.push({dis(i,j),j});
else{
if(nods[j].x-nods[i].x>h.top().first) break;
else if(dis(i,j)<h.top().first){
h.pop();
h.push({dis(i,j),j});
}
}
}
while(!h.empty()) edges.push_back({i,h.top().second,h.top().first}),h.pop();
}
std::sort(edges.begin(),edges.end());
for(i=1;i<=n;++i) par[i]=i,f[i][nods[i].val]=1;
for(auto edge:edges){
i=edge.x,j=edge.y;
if((pari=find(i))==(parj=find(j))) continue;
for(l=0;l<=k*2;++l) g[l]=0;
for(l=0;l<=k;++l)if(f[pari][l])
for(r=0;r<=k;++r)
g[l+r]|=f[parj][r];
for(l=0;l<=k*2;++l)
f[pari][l%k]|=g[l]|f[parj][l%k];
par[parj]=pari;
if(f[pari][0]){
printf("%.3lf",edge.dis);
break;
}
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}