【BZOJ】1821: [JSOI2010]Group 部落划分 Group(最小生成树+贪心)
http://www.lydsy.com:808/JudgeOnline/problem.php?id=1821
这题裸题。
本题要求最短距离最长,很明显,我们排序。
这里存在贪心,即我们把边权最小的全分给n个部落的内部,然后剩下的边最小的就是答案。
将边权较小的边分给k个部落,用并查集生成最小树,使得内部的边总是小于连到外部的边。然后分剩下k个点即可,剩下的k个点的那条边一定是部落之间最小的且最长的边。
#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <cmath> #include <algorithm> using namespace std; #define rep(i, n) for(int i=0; i<(n); ++i) #define for1(i,a,n) for(int i=(a);i<=(n);++i) #define for2(i,a,n) for(int i=(a);i<(n);++i) #define for3(i,a,n) for(int i=(a);i>=(n);--i) #define for4(i,a,n) for(int i=(a);i>(n);--i) #define CC(i,a) memset(i,a,sizeof(i)) #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define read(a) a=getnum() #define print(a) printf("%d", a) inline int getnum() { int ret=0; char c; int k=1; for(c=getchar(); c<‘0‘ || c>‘9‘; c=getchar()) if(c==‘-‘) k=-1; for(; c>=‘0‘ && c<=‘9‘; c=getchar()) ret=ret*10+c-‘0‘; return k*ret; } const int N=1005; int x[N], y[N]; struct edge { int u, v, w; bool operator < (const edge &a) const { return w<a.w; } }e[N*N]; int cnt; int f[N]; int ifind(const int &x) { return x==f[x]?x:f[x]=ifind(f[x]); } int main() { int n, m; read(n); read(m); for1(i, 1, n) read(x[i]), read(y[i]); for1(i, 1, n) f[i]=i; for1(i, 1, n) for1(j, 1, n) if(i!=j) e[cnt].u=i, e[cnt].v=j, e[cnt++].w=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]); sort(e, e+cnt); int fu, fv; for2(i, 0, cnt) { fu=ifind(e[i].u); fv=ifind(e[i].v); if(fu!=fv) { if(n>m) --n, f[fu]=fv; else { printf("%.2lf\n", sqrt(e[i].w)); break; } } } return 0; }
【BZOJ】1821: [JSOI2010]Group 部落划分 Group(最小生成树+贪心),古老的榕树,5-wow.com
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。