今天就做点kruskal的水题,晚一会儿继续做
POJ1251(水水水)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#define M 15005
using namespace std;
struct edge
{
int u;
int v;
int len;
}arr[M];
int fa[M];
bool cmp(edge a,edge b)
{
return a.len<b.len;
}
int frt(int x)
{
if(fa[x]==x)
return x;
return fa[x]=frt(fa[x]);
}
bool unite(int a,int b)
{
int ra=frt(a);
int rb=frt(b);
if(ra==rb)return false;
else
{
fa[ra]=rb;
}
return true;
}
int krus(int m,int n)
{ int cnt=0;
int sum=0;
for(int i=0;i<m;i++)
{
if(unite(arr[i].u,arr[i].v))
{
sum+=arr[i].len;
arr[cnt]=arr[i];
cnt++;
}
if(cnt>=n)break;
}
return sum;
}
int main()
{
int n;
char ch[5];
int m,cost;
int now;
int bian=0;
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
bian=0;
for(int i=0;i<27;i++)
fa[i]=i;
for(int i=0;i<n-1;i++)
{
scanf("%s %d",&ch,&m);
now=ch[0]-'A';
for(int j=0;j<m;j++)
{
scanf("%s %d",&ch,&cost);
arr[bian].u=now;
arr[bian].v=ch[0]-'A';
arr[bian++].len=cost;
}
}
sort(arr,arr+bian,cmp);
cout<<krus(bian,n)<<endl;
}
return 0;
}
POJ 2421(水题)
有些点在调用克鲁斯卡尔算法之前已经连边,注意一下处理就好
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
#define M 15005
using namespace std;
struct edge
{
int u,v;
double len;
} arr[M];
int fa[105];
bool cmp(edge a,edge b)
{
return a.len<b.len;
}
int fr(int x)
{
if(x!=fa[x])
fa[x]=fr(fa[x]);
return fa[x];
}
void unite(int a,int b)
{
int ra=fr(a);
int rb=fr(b);
if(ra!=rb)
fa[ra]=rb;
}
double kru(int n,int bian)
{
int ra;
int rb;
double sum=0;
for(int i=0; i<bian; i++)
{
ra=fr(arr[i].u);
rb=fr(arr[i].v);
if(ra!=rb)
{
fa[ra]=rb;
sum+=arr[i].len;
}
}
return sum;
}
int main()
{
int n;
cin>>n;
int x;
int bian=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
cin>>x;
if(i==j)
continue;
arr[bian].u=i+1;
arr[bian].v=j+1;
arr[bian++].len=x;
}
}
int q;
for(int i=1; i<=n; i++)
{
fa[i]=i;;
}
cin>>q;
int a,b;
while(q--)
{
cin>>a>>b;
unite(a,b);
}
sort(arr,arr+bian,cmp);
cout<<kru(n,bian)<<endl;
return 0;
}
POJ2031(稍微有点弯弯,实水)
就是有N个空间站,要通通连起来(庞统?),能到达就可以,最小生成树嘛,重叠的,接触的,就默认ok。
给出单点坐标和半径,求最小的需要搭建的走廊路径消耗
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
#define M 15005
using namespace std;
struct edge
{
int u,v;
double len;
}arr[M];
double xx[105];
double yy[105];
double zz[105];
double rr[105];
bool cmp(edge a,edge b)
{
return a.len<b.len;
}
double cal(int a,int b)
{
return sqrt((xx[a]-xx[b])*(xx[a]-xx[b])+(yy[a]-yy[b])*(yy[a]-yy[b])+(zz[a]-zz[b])*(zz[a]-zz[b]))-rr[a]-rr[b];
}
int fa[105];
int fr(int x)
{
if(x!=fa[x]) fa[x]=fr(fa[x]);
return fa[x];
}
double kru(int n,int bian)
{
int ra;
int rb;
int cnt=0;
double sum=0;
for(int i=0;i<bian;i++)
{
ra=fr(arr[i].u);
rb=fr(arr[i].v);
if(ra!=rb)
{ fa[ra]=rb;
sum+=arr[i].len;
cnt++;
}
if(cnt>=n) break;
}
return sum;
}
int main()
{
int n,m;
double x,y,z;
double dis;
while(cin>>n&&n!=0)
{
for(int i=0;i<n;i++)
{
cin>>xx[i]>>yy[i]>>zz[i]>>rr[i];
}
for(int i=0;i<n;i++)
{
fa[i]=i;
}
int bian=0;
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
dis = cal(i,j);
if(dis<0) dis=0;
arr[bian].u=i;
arr[bian].v=j;
arr[bian++].len=dis;
}
}
sort(arr,arr+bian,cmp);
cout<<fixed<<setprecision(3)<<kru(n,bian)<<endl;
}
return 0;
}