HDOJ 1435 Stable Match

Stable Match

TimeLimit: 2000/1000 MS (Java/Others)    Memory Limit:65536/32768 K (Java/Others)
Total Submission(s): 744    Accepted Submission(s): 354
Special Judge

Problem Description

Network公司的BOSS 说现在他们公司建立的信号发射站和接收站经常出现信号发送接收不稳定的问题,信号的稳定度被定义为发射点到接收点的距离,距离越大,越不稳定,所以发射点跟接收点在可能的情况下应越近越好.
BOSS
8600的任务就是::建立一个匹配表,使得一个发射点对应一个接收点,对于某一个发射点来说,它的接收点离它越近那么就会更稳定,同样对于接收点也是一样的情况. 匹配的目标是使得整个网络变得稳定。,对于某2个匹配,比如,( a---- 1) ,(b----2) ,如果发射点a 离接收点2 1要近,而且2 也离 发射点a要比 b , 那么 a 就很有可能把信号发到 2,我们就说这个搭配是不 稳定的。同样如果发射点b 离接收点1 2 要近,而且1 也离 发射点b要比 a ,也会出现不稳定的情 . 而且每个点都有一个容量值,如果对于一个发射点到2个接收点的距离一样的话,它将首先选择容量大的那个. 所以8600就是要建立一个稳定的匹配,使得每个一个信号发射点对应一个接收点,并且不会出现信号不稳定的情况.
8600
苦思冥想也没什么进展,希望你能帮他解决这个难题.

 

 

Input

输入数据首先包含一个正整数N,N<=20表示测试实例的个数.每个实例首先是一个整C,C<=200表示有C个信号发射点和C个信号接收点. 接下来的C行表示 C个发射点的编号,容量和坐标,坐标为,x,y,z3个实数(x,y,z≥0).最后C行是C个接收点的编号,容量和坐标.

 

 

Output

输出建立稳定搭配后各个发射点和接收点的编号,每一行代表一个搭配,前一个整数为发射点的编号,后一个为对应的接收点的编号。如果有多种情况,输出其中一种即可.如果任务不可能完成的话,输出"Impossible".每个实例后请输出一个空行.

 

 

Sample Input

1

3

1 1 60.57 57.1669.27

2 2 26.05 61.0611.52

3 3 9.04 58.2056.90

1 2 280.74 12.78316.14

2 3 305.16 267.1587.65

3 1 240.72 312.41217.10

 

 

Sample Output

3 1

1 2

2 3



#include <bits/stdc++.h>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define f(i,a,b) for(int i=(a);i<=(b);++i)
#define ll long long
const int maxn = 205;
const int mod = 475;
const ll INF = 0x3f3f3f3f;
const double eps = 1e-6;
#define rush() int T;scanf("%d",&T);while(T--)
struct node
{
    double x,y,z;
    int id,w;
}c1[maxn],c2[maxn];
struct no
{
    int id,w;
    double dis;
}p[maxn];
double getdis(node a,node b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z);
}
bool cmp(no a,no b)
{
    if(a.dis==b.dis)
    {
        return a.w>b.w;
    }
    return a.dis<b.dis;
}
int b[maxn][maxn],g[maxn][maxn],flag[maxn];
int bm[maxn],gm[maxn],order[maxn];
int n;
int main()
{
    int t,u;
    scanf("%d",&t);
    while(t--)
    {
        queue<int>q;
        mst(bm,0),mst(gm,0);
        mst(b,0),mst(g,0);
        mst(flag,0);
        scanf("%d",&n);
        f(i,1,n)
        {
            scanf("%d%d%lf%lf%lf",&c1[i].id,&c1[i].w,&c1[i].x,&c1[i].y,&c1[i].z);
            q.push(c1[i].id);
        }
        f(i,1,n)
        {
            scanf("%d%d%lf%lf%lf",&c2[i].id,&c2[i].w,&c2[i].x,&c2[i].y,&c2[i].z);
        }
        f(i,1,n)
        {
            mst(p,0);
            f(j,1,n)
            {
                p[j].dis=getdis(c1[i],c2[j]);
                p[j].id=c2[j].id;
                p[j].w=c2[j].w;
            }
            sort(p+1,p+1+n,cmp);
            f(j,1,n)
            {
                b[c1[i].id][j]=p[j].id;
            }
            order[c1[i].id]=1;
        }
        f(i,1,n)
        {
            mst(p,0);
            f(j,1,n)
            {
                p[j].dis=getdis(c2[i],c1[j]);
                p[j].id=c1[j].id;
            }
            sort(p+1,p+n+1,cmp);
            f(j,1,n)
            {
                g[c2[i].id][p[j].id]=j;
            }
        }
        while(q.size())
        {
            int cur=q.front();
            q.pop();
            u=b[cur][order[cur]++];
            if(!gm[u])
            {
                gm[u]=cur;
                bm[cur]=u;
            }
            else if(g[u][cur]<g[u][gm[u]])
            {
                bm[gm[u]]=0;
                q.push(gm[u]);
                gm[u]=cur;
                bm[cur]=u;
            }
            else
            {
                q.push(cur);
            }
        }
        f(i,1,n)
        {
            printf("%d %d\n",c1[i].id,bm[c1[i].id]);
        }
        if(t)
            printf("\n");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值