并查集题解

来源:互联网 发布:精锐摇杆石头淘宝店 编辑:程序博客网 时间:2024/05/16 06:01

http://acm.hdu.edu.cn/diy/contest_show.php?cid=18639


1001 畅通工程

这题简单,只要把有连边的点合并。最后查看一下有几个不同的集合,集合数减1就是要建路的个数。

1002 小希的迷宫

本题实际上就是让你判断所给的边组成的是不是一棵树,本题是无向树,无向树是任意两点有且仅有一条通路,也就是没回路且联通。

因此,每读入一条边,先判断该两点是否已经通了,在同一个集合,是就说明不是一棵树,不是就合并这两个集合。同时看这两个顶点是否出现过,如果没出现则需要记录一下。

等这些工作完成后,在遍历一下出现过的顶点如果全在一个集合就说明是树,否则就不是。

1003 Farm Irrigation

这题存取方向稍稍有点难度,这个待会再说,假设已经知道了当前的方格是否和上下左右联通,那么只要将联通的方格合并,最后遍历一遍看有几个集合,就是所要求的答案

存取当前方格是否和前后左右联通。

1状态压缩,用二进制位的10代表是否和上下左右联通。

dd[]={3,6,9,12,10,5,7,11,13,14,15};

2

char ll[]={'A','C','F','G','H','I','K'};
char rr[]={'B','D','F','G','I','J','K'};
char up[]={'A','B','E','G','H','J','K'};
char dd[]={'C','D','E','H','I','J','K'};

 for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    vis[0][rr[i]][ll[j]]=1;
  for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    vis[1][dd[i]][up[j]]=1;

这样就可以直接判断任意两个是否联通

1004 More is better

简单题,就是合并输入的两个数所在的集合,然后输出集合元素最多的那个集合的元素个数,注意当输入是0时输出为1

1005 find the most comfortable road

这题先将读入的按照速度排序,然后枚举任意两个之间连续速度段的,如果起点和终点都在其中那就是一种方案,依次更新,找出相差最小的即可

1006 A Bug's Life

本题是并查集的应用,有点难度,存的是关系,一个集合中的元素是能够经过相互之间确定关系的,因此每读入两个bug的关系,先判断是不是一个集合,也就是相互之间的

关系是否已经确立,如果没有就合并,确立关系,如果已经确立,就判断原先的关系和现在的关系是否有冲突。

1007 How Many Tables

简单题,合并看有几个不同的集合

1008 Is It A Tree?

本题和小希的迷宫很像,唯一的不同是,本题是有向树,只要在小希的迷宫的基础上,再加个判断只有一个点入度为0,其他的点入度均是1那就是树

1009 重题了,我的失误

1010 Constructing Roads

本题是最小树,用二维矩阵存边,然后将已经连边的权改为0,而后根据边权排序,从小到大加边,若边两点不是一个集合,就合并,边权加上。

最后输出者个和就行了

1011 还是畅通工程

最小树

1012 畅通工程

最小树,最后判断一下是不是就一个集合

1013 畅通工程再续

最小树,边权是浮点数,自己算

1014 继续畅通工程

最小树,将已经建的边权改为0

1015 Connect the Cities

最小树,最后判断是否只有一个集合

1016 Jungle Roads

最小树

1017 Eddy's picture

最小树

后两题重了。

 

1001

#include<iostream>
#include<cstring>
using namespace std;
const int mm=1e3+9;
int n,m;
int root[mm];
void dataset()
{
  for(int i=0;i<n;i++)
    root[i]=i;
}
int look(int x)
{
  if(x^root[x])
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{
  x=look(x);y=look(y);root[x]=y;
}
int main()
{
  while(cin>>n&&n)
  { cin>>m;
    dataset();
    int a,b;
    for(int i=0;i<m;i++)
    {
      cin>>a>>b;--a;--b;
      if(look(a)^look(b))
      uni(a,b);
    }
    int ans=0;
    for(int i=0;i<n;i++)
      if(root[i]==i)
      ++ans;
      --ans;
    cout<<ans<<"\n";
  }
}
1002
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1e5+9;
int n,m;
int root[mm],num[mm],pos;
bool vis[mm];
void dataset()
{ memset(vis,0,sizeof(vis));
  pos=0;
  for(int i=0;i<mm;i++)
    root[i]=i;
}
int look(int x)
{
  if(x^root[x])
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{
  x=look(x);y=look(y);root[x]=y;
}
int main()
{ int a,b;
  while(cin>>a>>b)
  { if(a==-1&&b==-1)break;
    if(a==0&&b==0){cout<<"Yes\n";continue;}
    dataset();
    if(!vis[a]){vis[a]=1;num[pos++]=a;}
    if(!vis[b]){vis[b]=1;num[pos++]=b;}
    if(a^b)uni(a,b);
    bool flag=0;
    while(cin>>a>>b)
    { if(a==0&&b==0)break;
      if(!vis[a]){vis[a]=1;num[pos++]=a;}
      if(!vis[b]){vis[b]=1;num[pos++]=b;}
      if(a==b)continue;
      if(look(a)==look(b))flag=1;
      else uni(a,b);
    }
    int z=look(num[0]);
    for(int i=1;i<pos;i++)
      if(look(num[i])^z)
      {
        flag=1;break;
      }
    if(flag)cout<<"No\n";
    else cout<<"Yes\n";
  }
}
1003
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1e3+9;
char ll[]={'A','C','F','G','H','I','K'};
char rr[]={'B','D','F','G','I','J','K'};
char up[]={'A','B','E','G','H','J','K'};
char dd[]={'C','D','E','H','I','J','K'};
int root[mm*100];
bool vis[2][mm][mm];
char s[mm][mm];
void dataset(int x)
{
  for(int i=0;i<=x;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{
  a=look(a);b=look(b);root[a]=b;
}
int main()
{ int m,n;
  memset(vis,0,sizeof(vis));
  for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    vis[0][rr[i]][ll[j]]=1;
  for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    vis[1][dd[i]][up[j]]=1;
  while(cin>>m>>n)
  { if(m==-1&&n==-1)break;
    dataset(m*n);
    for(int i=0;i<m;i++)
      cin>>s[i];
    for(int i=0;i<m;i++)
      for(int j=0;j<n;j++)
    {
      if(j&&vis[0][s[i][j-1]][s[i][j]])uni(i*n+j-1,i*n+j);
      if(i&&vis[1][s[i-1][j]][s[i][j]])uni((i-1)*n+j,i*n+j);
    }
    int z=m*n,ans=0;
    for(int i=0;i<z;i++)
      if(look(i)==i)
      ++ans;
    cout<<ans<<"\n";
  }
}
1004
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1e7+9;
int root[mm],ran[mm],ans;
void data()
{
  for(int i=0;i<mm;i++)
    root[i]=i,ran[i]=1;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{
  a=look(a);b=look(b);
  if(a==b)return;
  if(ran[a]>ran[b])root[b]=a,ran[a]+=ran[b];
  else root[a]=b,ran[b]+=ran[a];
  if(ans<ran[a])ans=ran[a];
  if(ans<ran[b])ans=ran[b];
}
int main()
{ int n;
  while(cin>>n)
  { int a,b;
    data();
    ans=0;
    for(int i=0;i<n;i++)
    {
      cin>>a>>b;
      if(a^b)
      uni(a,b);
    }
    if(n==0)ans=1;
    cout<<ans<<"\n";
  }
}
1005
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int mm=1100;
const int oo=1e9;
int n,m,root[mm];
class node
{
  public:int u,v,c;
}f[mm];
bool cmp(node a,node b)
{
  return a.c<b.c;
}
void data()
{
  for(int i=1;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{
  a=look(a);b=look(b);root[a]=b;
}
int main()
{
  while(cin>>n>>m)
  {
    for(int i=0;i<m;i++)
      cin>>f[i].u>>f[i].v>>f[i].c;
    sort(f,f+m,cmp);
    int z,a,b;cin>>z;
    for(int i=0;i<z;i++)
    {
      cin>>a>>b;int ans=oo;
      for(int i=0;i<m;i++)
       { data();
         for(int j=i;j<m;j++)
        {
          uni(f[j].u,f[j].v);
          if(look(a)==look(b))
            {
              if(ans>f[j].c-f[i].c)
                ans=f[j].c-f[i].c;
            }
        }
       }
       if(ans==oo)cout<<-1<<"\n";
       else cout<<ans<<"\n";
    }
  }
}
1006
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=2100;
const int mod=2;
int root[mm],kind[mm];
int n,m;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i,kind[i]=0;
}
int look(int x)
{ int z;
  if(root[x]^x)
  {
    z=root[x];
    root[x]=look(root[x]);
    kind[x]=(kind[z]+kind[x])%mod;
  }
  return root[x];
}
void uni(int ra,int rb,int a,int b)
{
  root[ra]=rb;kind[ra]=(kind[a]+kind[b]+1)%mod;
}
int main()
{ int cas;
  cin>>cas;
  for(int kk=1;kk<=cas;kk++)
  {
    cin>>n>>m; bool flag=0;
    data();int a,b,ra,rb;
    for(int i=0;i<m;i++)
    {
      cin>>a>>b;
      ra=look(a);rb=look(b);
      if(ra^rb)uni(ra,rb,a,b);
      else
      {
        if(kind[a]==kind[b])flag=1;
      }
    }
    if(flag)printf("Scenario #%d:\nSuspicious bugs found!\n",kk);
    else printf("Scenario #%d:\nNo suspicious bugs found!\n",kk);
    printf("\n");
  }
}
1007
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=2100;
const int mod=2;
int root[mm],kind[mm];
int n,m;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{ int z;
  if(root[x]^x)
  root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{ a=look(a);b=look(b);
  if(a^b)root[a]=b;
}
int main()
{ int cas;
  cin>>cas;
  for(int kk=1;kk<=cas;kk++)
  {
    cin>>n>>m;
    data();int a,b;
    for(int i=0;i<m;i++)
    {
      cin>>a>>b;
      if(a^b)uni(a,b);
    }
    int ans=0;
    for(int i=1;i<=n;i++)
      if(look(i)==i)
      ++ans;
    cout<<ans<<"\n";
  }
}
1008
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=1e5+9;
int id[mm];
int n,m;
int root[mm],num[mm],pos;
bool vis[mm];
void dataset()
{ memset(vis,0,sizeof(vis));
  memset(id,0,sizeof(id));
  pos=0;
  for(int i=0;i<mm;i++)
    root[i]=i;
}
int look(int x)
{
  if(x^root[x])
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{
  x=look(x);y=look(y);root[x]=y;
}
int main()
{ int a,b,cas=0;
  while(cin>>a>>b)
  { ++cas;  bool flag=0;
    if(a<0&&b<0)break;
    if(a==0&&b==0){printf("Case %d is a tree.\n",cas);continue;}
    dataset();++id[b];
    if(!vis[a]){vis[a]=1;num[pos++]=a;}
    if(!vis[b]){vis[b]=1;num[pos++]=b;}
    if(a^b)uni(a,b);
    else flag=1;
    while(cin>>a>>b)
    { if(a==0&&b==0)break;
      if(!vis[a]){vis[a]=1;num[pos++]=a;}
      if(!vis[b]){vis[b]=1;num[pos++]=b;}
      ++id[b];if(id[b]>1)flag=1;
      if(a==b){flag=1;continue;}
      if(look(a)==look(b))flag=1;
      else uni(a,b);
    }
    int z=look(num[0]);
    for(int i=1;i<pos;i++)
      if(look(num[i])^z)
      {
        flag=1;break;
      }
    if(flag)printf("Case %d is not a tree.\n",cas);
    else printf("Case %d is a tree.\n",cas);
  }
}
1009
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1e7+9;
int root[mm],ran[mm],ans;
void data()
{
  for(int i=0;i<mm;i++)
    root[i]=i,ran[i]=1;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{
  a=look(a);b=look(b);
  if(a==b)return;
  if(ran[a]>ran[b])root[b]=a,ran[a]+=ran[b];
  else root[a]=b,ran[b]+=ran[a];
  if(ans<ran[a])ans=ran[a];
  if(ans<ran[b])ans=ran[b];
}
int main()
{ int n;
  while(cin>>n)
  { int a,b;
    data();
    ans=0;
    for(int i=0;i<n;i++)
    {
      cin>>a>>b;
      if(a^b)
      uni(a,b);
    }
    if(n==0)ans=1;
    cout<<ans<<"\n";
  }
}
1010
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int mm=110;
class node
{
  public:int a,b,c;
}f[mm*mm];
int n;
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],g[mm][mm],pos;
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{
  while(cin>>n)
  {
   for(int i=0;i<n;i++)
   { root[i]=i;
     for(int j=0;j<n;j++)
      cin>>g[i][j];
   }
   int m;
   cin>>m;int a,b;
   for(int i=0;i<m;i++)
   {
     cin>>a>>b;--a;--b;
     g[a][b]=g[b][a]=0;
   }
   pos=0;
   for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
      f[pos].a=i,f[pos].b=j,f[pos].c=g[i][j],pos++;
    sort(f,f+pos,cmp);
    int u,v,c,ans=0;
    for(int i=0;i<pos;i++)
    { u=f[i].a;v=f[i].b;c=f[i].c;
      if(look(u)^look(v))
      {uni(u,v);
       ans+=c;
      }
    }
    cout<<ans<<"\n";
  }
}
1011
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=110;
class node
{
  public:int a,b,c;
}f[mm*mm];
int n;
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],g[mm][mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{
  while(scanf("%d",&n)!=EOF)
  { if(n==0)break;
    data();
   int z=n*(n-1);z/=2;
   int a,b,c;
   for(int j=0;j<z;j++)
    {
      cin>>f[j].a>>f[j].b>>f[j].c;
    }
    sort(f,f+z,cmp);
    int ans=0;
    for(int i=0;i<z;i++)
    { a=f[i].a;b=f[i].b;c=f[i].c;
      if(look(a)^look(b))
        uni(a,b),ans+=c;
    }
    cout<<ans<<"\n";
  }
}
1012
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=110;
class node
{
  public:int a,b,c;
}f[mm*mm];
int n,m;
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],g[mm][mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{
  while(scanf("%d%d",&m,&n)!=EOF)
  { if(m==0)break;
    data();
   int a,b,c;
   for(int j=0;j<m;j++)
    {
      cin>>f[j].a>>f[j].b>>f[j].c;
    }
    sort(f,f+m,cmp);
    int ans=0,num=0;
    for(int i=0;i<m;i++)
    { a=f[i].a;b=f[i].b;c=f[i].c;
      if(look(a)^look(b))
        uni(a,b),ans+=c,++num;
    }
    if(num==n-1)
    cout<<ans<<"\n";
    else cout<<"?\n";
  }
}
1013
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=210;
class node
{
  public:int a,b;double c,x,y;
}f[mm*mm],ff[mm];
int n,m;
double dis(node a,node b)
{
  double z=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
  z=sqrt(z);
  return z;
}
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{ int cas;
  scanf("%d",&cas);
   while(cas--)
    {scanf("%d",&n);
      data();
   for(int j=0;j<n;j++)
    { scanf("%lf%lf",&ff[j].x,&ff[j].y);
    }
    pos=0;
    for(int i=0;i<n;i++)
      for(int j=i+1;j<n;j++)
      {
        double c=dis(ff[i],ff[j]);
        if(c<10.0||c>1000.0)continue;
        f[pos].a=i,f[pos].b=j,f[pos].c=c,pos++;
      }
    sort(f,f+pos,cmp);
    int num=0;double ans=0.0;
    int a,b;double c;
    for(int i=0;i<pos;i++)
    { a=f[i].a;b=f[i].b;c=f[i].c;
      if(look(a)^look(b))
        uni(a,b),ans+=c,++num;
      if(num==n-1)break;
    }
    ans*=100.0;
    if(num==n-1)
    printf("%.1lf\n",ans);
    else printf("oh!\n");

  }
}
1014
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=210;
class node
{
  public:int a,b,c;
}f[mm*mm];
int n,m;
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{
   while(scanf("%d",&n)&&n)
    {int z=n*(n-1);z/=2;
      data();
    pos=0;
    int a,b,c,d;
    for(int i=0;i<z;i++)
    {
      cin>>a>>b>>c>>d;
      if(!d)
      {
        f[pos].a=a;f[pos].b=b;f[pos].c=c;pos++;
      }
      else uni(a,b);
    }
    sort(f,f+pos,cmp);
    int num=0,ans=0;
    for(int i=0;i<pos;i++)
    { a=f[i].a;b=f[i].b;c=f[i].c;
      if(look(a)^look(b))
        uni(a,b),ans+=c,++num;
      //if(num==n-1)break;
    }
   // if(num==n-1)
    printf("%d\n",ans);
   // else printf("oh!\n");

  }
}
1015
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=510;
class node
{
  public:int a,b,c;
}f[25100];
int n,m,k;
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{
  int cas;
    scanf("%d",&cas);
    while(cas--)
    {scanf("%d%d%d",&n,&m,&k);
    data();
    int a,b,c;
    for(int i=0;i<m;i++)
    { scanf("%d%d%d",&f[i].a,&f[i].b,&f[i].c);
      //cin>>f[i].a>>f[i].b>>f[i].c;
    }
    for(int i=0;i<k;i++)
    { scanf("%d",&c);
      //cin>>c;
      if(c){//cin>>a;
      scanf("%d",&a);
      a=look(a);}
      for(int j=1;j<c;j++)
        {scanf("%d",&b);
          //cin>>b;
          uni(b,a);
        }
    }
    int num=0,ans=0;
    for(int i=1;i<=n;i++)
      if(i==look(i))
      ++num;
    sort(f,f+m,cmp);
    for(int i=0;i<m;i++)
    { a=look(f[i].a);b=look(f[i].b);c=f[i].c;
      if(a^b)
        uni(a,b),--num,ans+=c;
      if(num==1)break;
    }
    if(num==1)printf("%d\n",ans);
    else printf("%d\n",-1);

  }
}
1016
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=510;
class node
{
  public:int a,b,c;
}f[25100];
int n,m,k;
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{
  while(scanf("%d",&n)&&n)
  {  char a,b;int c;
     data();pos=0;
    for(int i=1;i<n;i++)
    {
      cin>>a>>m;
      for(int j=0;j<m;j++)
      {
        cin>>b>>c;
        f[pos].a=a-'A';f[pos].b=b-'A';f[pos].c=c,pos++;
      }
    }
    sort(f,f+pos,cmp);
    int num=0,ans=0,x,y;
    for(int i=0;i<pos;i++)
    {
      x=look(f[i].a);y=look(f[i].b);c=f[i].c;
      if(x^y)
        uni(x,y),++num,ans+=c;
      if(num==n-1)break;
    }
    cout<<ans<<"\n";
  }
}
1017
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
const int mm=210;
class node
{
  public:int a,b;double c,x,y;
}f[mm*mm],ff[mm];
int n,m;
double dis(node a,node b)
{
  double z=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
  z=sqrt(z);
  return z;
}
bool cmp(node a,node b)
{
  return a.c<b.c;
}
int root[mm],pos;
void data()
{
  for(int i=0;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int x,int y)
{ x=look(x);y=look(y);
  root[x]=y;
}
int main()
{ int cas;
   while(scanf("%d",&n)!=EOF)
    {
      data();
   for(int j=0;j<n;j++)
    { scanf("%lf%lf",&ff[j].x,&ff[j].y);
    }
    pos=0;
    for(int i=0;i<n;i++)
      for(int j=i+1;j<n;j++)
      {
        double c=dis(ff[i],ff[j]);
        ///if(c<10.0||c>1000.0)continue;
        f[pos].a=i,f[pos].b=j,f[pos].c=c,pos++;
      }
    sort(f,f+pos,cmp);
    int num=0;double ans=0.0;
    int a,b;double c;
    for(int i=0;i<pos;i++)
    { a=f[i].a;b=f[i].b;c=f[i].c;
      if(look(a)^look(b))
        uni(a,b),ans+=c,++num;
      if(num==n-1)break;
    }
    if(num==n-1)
    printf("%.2lf\n",ans);
    else printf("oh!\n");

  }
}
1018
#include<iostream>
#include<cstring>
using namespace std;
const int mm=1e3+9;
char ll[]={'A','C','F','G','H','I','K'};
char rr[]={'B','D','F','G','I','J','K'};
char up[]={'A','B','E','G','H','J','K'};
char dd[]={'C','D','E','H','I','J','K'};
int root[mm*100];
bool vis[2][mm][mm];
char s[mm][mm];
void dataset(int x)
{
  for(int i=0;i<=x;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{
  a=look(a);b=look(b);root[a]=b;
}
int main()
{ int m,n;
  memset(vis,0,sizeof(vis));
  for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    vis[0][rr[i]][ll[j]]=1;
  for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    vis[1][dd[i]][up[j]]=1;
  while(cin>>m>>n)
  { if(m==-1&&n==-1)break;
    dataset(m*n);
    for(int i=0;i<m;i++)
      cin>>s[i];
    for(int i=0;i<m;i++)
      for(int j=0;j<n;j++)
    {
      if(j&&vis[0][s[i][j-1]][s[i][j]])uni(i*n+j-1,i*n+j);
      if(i&&vis[1][s[i-1][j]][s[i][j]])uni((i-1)*n+j,i*n+j);
    }
    int z=m*n,ans=0;
    for(int i=0;i<z;i++)
      if(look(i)==i)
      ++ans;
    cout<<ans<<"\n";
  }
}
1019
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int mm=1100;
const int oo=1e9;
int n,m,root[mm];
class node
{
  public:int u,v,c;
}f[mm];
bool cmp(node a,node b)
{
  return a.c<b.c;
}
void data()
{
  for(int i=1;i<=n;i++)
    root[i]=i;
}
int look(int x)
{
  if(root[x]^x)
    root[x]=look(root[x]);
  return root[x];
}
void uni(int a,int b)
{
  a=look(a);b=look(b);root[a]=b;
}
int main()
{
  while(cin>>n>>m)
  {
    for(int i=0;i<m;i++)
      cin>>f[i].u>>f[i].v>>f[i].c;
    sort(f,f+m,cmp);
    int z,a,b;cin>>z;
    for(int i=0;i<z;i++)
    {
      cin>>a>>b;int ans=oo;
      for(int i=0;i<m;i++)
       { data();
         for(int j=i;j<m;j++)
        {
          uni(f[j].u,f[j].v);
          if(look(a)==look(b))
            {
              if(ans>f[j].c-f[i].c)
                ans=f[j].c-f[i].c;
            }
        }
       }
       if(ans==oo)cout<<-1<<"\n";
       else cout<<ans<<"\n";
    }
  }
}