poj 2349 Arctic Network
Sol:
方法一:
贪心的想,发现n个点只需要n-1条边即可,求MST即可,再把MST中最大的m-1条边去掉,第m大就是答案。
code:
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define IL inline
#define RG register
#define DB double
#define LL long long
using namespace std;
IL int gi() {
RG int x=0,p=1; RG char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') p=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*p;
}
const int N=507;
DB d[N];
int n,m,tot,fa[N];
struct DOT{int x,y;}a[N];
struct EDGE{int x,y;DB d;}e[N*N<<1];
IL bool operator <(EDGE A,EDGE B) {return A.d<B.d;}
IL DB dis(int s,int b) {
return sqrt(1.0*(a[s].x-a[b].x)*(a[s].x-a[b].x)+(a[s].y-a[b].y)*(a[s].y-a[b].y));
}
int getfa(int x) {return fa[x]==x?x:fa[x]=getfa(fa[x]);}
IL void Kruskal() {
RG int i,fx,fy,cnt=0;
for(i=1;i<=n;++i) fa[i]=i;
for(i=1;i<=tot;++i) {
fx=getfa(e[i].x),fy=getfa(e[i].y);
if(fx==fy) continue;
fa[fx]=fy,d[++cnt]=e[i].d;
if(cnt==n-1) break;
}
printf("%.2lf
",d[n-m]);//poj 上如用G++交代码,则需把%lf改为%f
}
int main()
{
RG int i,j,T=gi();
while(T--) {
m=gi(),n=gi(),tot=0;
for(i=1;i<=n;++i) a[i].x=gi(),a[i].y=gi();
for(i=1;i<=n;++i)
for(j=i+1;j<=n;++j)
e[++tot]=(EDGE){i,j,dis(i,j)};
sort(e+1,e+tot+1);
Kruskal();
}
return 0;
}
//poj 145ms
方法二:
考虑二分答案,满足条件的点连好边,然后dfs一下有几个连通块,有多少连通块就需要多少卫星,和m比较即可。
相比方法一,code又慢又长。。。
code:
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
#define IL inline
#define RG register
#define DB double
#define LL long long
using namespace std;
IL int gi() {
RG int x=0,p=1; RG char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') p=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*p;
}
const int N=505;
const DB eps=1e-4;
DB l,r,mid;
int n,m,cnt,tot,vis[N],head[N];
struct DOT{int x,y;}a[N];
struct EDGE{int next,to;}e[N*N<<1];
IL void New_case() {
tot=cnt=0;
memset(&e,0,sizeof(e));
memset(vis,0,sizeof(vis));
memset(head,0,sizeof(head));
}
IL void make(int x,int y) {
e[++tot]=(EDGE){head[x],y},head[x]=tot;
e[++tot]=(EDGE){head[y],x},head[y]=tot;
}
IL DB dis(int s,int b) {
return 1.0*sqrt((a[s].x-a[b].x)*(a[s].x-a[b].x)+(a[s].y-a[b].y)*(a[s].y-a[b].y));
}
IL void dfs(int x) {
RG int i,y;
vis[x]=1;
for(i=head[x];i;i=e[i].next)
if(!vis[y=e[i].to]) dfs(y);
}
IL int check(DB val) {
RG int i,j;
New_case();
for(i=1;i<=n;++i)
for(j=i+1;j<=n;++j)
if(dis(i,j)<=val) make(i,j);
for(i=1;i<=n;++i)
if(!vis[i]) dfs(i),++cnt;
return cnt<=m;
}
int main()
{
RG int i,T=gi();
while(T--) {
m=gi(),n=gi();
for(i=1;i<=n;++i) a[i].x=gi(),a[i].y=gi();
l=0,r=1e9;
while(r-l>=eps) {
mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
printf("%.2lf
",r);
}
return 0;
}
// poj 1400多ms