您的位置:首页 > 其它

Another Minimum Spanning Tree - UVaLive 3662 曼哈顿最小生成树

2015-06-14 12:27 405 查看
For a given point set P = {(xi, yi) : 1

i

n},
then construct a complete graph G = (V, E, W) with nvertexes. The weight function for any two vertexes is w(vi, vj)
= | xi - xj| + | yi - yj|. Please calculate the minimum spanning tree of G.

Hint

For the graph below, there exists a minimum spanning tree in which there is at most one vertex connected withA in
the shadow area. You can extend this property to solve the problem.



Input

Input contains several cases.
Each cases begins with an integer n, 1

n

100,
000, to indicate the size of the point set. The points in the point set have serial numbers from 1 to n.
Each line of the following n lines contains two non-negative integers (xi, yi) (no more than 107)
to describe the coordinate for each point. Any two points' coordinates are different.
The last case is followed by a line containing a zero.

Output

For each case, output the case's serial number and the weighted sum of all minimum spanning tree edges in the following format.

Sample Input

3
0 0
2 0
0 3
0


Sample Output

Case 1: Total Weight = 5


题意:求曼哈顿最小生成树。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
struct node
{
    int x,y,pos;
}point[100010];
struct node2
{
    int u,v,w;
}edge[40000010];
int T,t,n,N=40000020,tot,p[100010],c[40000020],d[40000020],INF=1e9;
bool cmp(node a,node b)
{
    return a.x<b.x || (a.x==b.x && a.y<b.y);
}
bool cmp2(node2 a,node2 b)
{
    return a.w<b.w;
}
int lowbit(int x)
{
    return x&(-x);
}
int find(int x)
{
    return x==p[x] ? x : p[x]=find(p[x]);
}
void query(int val,int w,int pos)
{
    int id=-1,minn=INF,i;
    val+=20000010;
    for(i=val;i<N;i+=lowbit(i))
       if(c[i]<minn)
       {
           minn=c[i];
           id=d[i];
       }
    if(id!=-1)
    {
        tot++;
        edge[tot].u=pos;
        edge[tot].v=id;
        edge[tot].w=minn-w;
    }
}
void update(int val,int w,int pos)
{
    int i,j,k;
    val+=20000010;
    for(i=val;i>0;i-=lowbit(i))
       if(w<c[i])
       {
           c[i]=w;
           d[i]=pos;
       }
}
void go()
{
    int i,j,k;
    sort(point+1,point+1+n,cmp);
    for(i=1;i<N;i++)
       c[i]=INF;
    for(i=n;i>=1;i--)
    {
        query(point[i].y-point[i].x,point[i].y+point[i].x,point[i].pos);
        update(point[i].y-point[i].x,point[i].y+point[i].x,point[i].pos);
    }
}
ll work()
{
    int i,j,k,u,v;
    ll ans=0;
    tot=0;
    go();
    for(i=1;i<=n;i++)
       swap(point[i].x,point[i].y);
    go();
    for(i=1;i<=n;i++)
       point[i].y=-point[i].y;
    go();
    for(i=1;i<=n;i++)
       swap(point[i].x,point[i].y);
    go();
    sort(edge+1,edge+1+tot,cmp2);
    for(i=1;i<=n;i++)
       p[i]=i;
    for(i=1;i<=tot;i++)
    {
        u=find(edge[i].u);
        v=find(edge[i].v);
        if(u==v)
          continue;
        p[u]=v;
        ans+=edge[i].w;
    }
    return ans;
}
int main()
{
    int i,j,k;
    ll ans;
    while(~scanf("%d",&n) && n>0)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&point[i].x,&point[i].y);
            point[i].pos=i;
        }
        ans=work();
        printf("Case %d: Total Weight = %lld\n",++t,ans);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: