HDU 1435(Stable Match)

稳定匹配问题,首先计算所有发射站匹配接收站的顺序和所有接收站匹配发射站的顺序,然后对于每个发射站,按照其匹配序列依次和接收站匹配,分为两种情况:

  1. 接收站未匹配,则该发射站和接收站匹配;
  2. 接收站已匹配,如果该发射站和接收站的匹配程度大于接收站和当前匹配的发射站的匹配程度,则该发射站和接收站匹配,接收站之前匹配的发射站置为未匹配状态。

重复上述操作,直到所有发射站和接收站都匹配。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 205;
const double eps = 1e-8;

struct Couple //一对发射站和接收站
{
    int num; //编号
    int v; //容量
    double dis; //距离
}couple[MAXN];

struct Point //结点
{
    double x, y, z; //坐标
    int v; //容量
}s[MAXN], e[MAXN]; //发射站数组,接收站数组

int C; //发射站和接收站的数量
int rankS[MAXN][MAXN], rankE[MAXN][MAXN]; //发射站匹配接收站的顺序,接收站匹配发射站的顺序
int matchS[MAXN], matchE[MAXN]; //发射站匹配的接收站,接收站匹配的发射站
int nextS[MAXN]; //发射站准备匹配的接收站

//计算p1和p2两点的距离
double getDis(Point p1, Point p2)
{
    return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z);
}

//排序标准
bool cmp(Couple c1, Couple c2)
{
    if (fabs(c1.dis - c2.dis) < eps)
        return c1.v > c2.v;
    else
        return c1.dis < c2.dis;
}

//计算所有发射站匹配接收站的顺序和所有接收站匹配发射站的顺序
void getRank()
{
    for (int i = 1; i <= C; i++)
    {
        for (int j = 1; j <= C; j++)
        {
            couple[j].num = j;
            couple[j].v = e[j].v;
            couple[j].dis = getDis(s[i], e[j]);
        }
        sort(couple + 1, couple + C + 1, cmp);
        for (int j = 1; j <= C; j++)
            rankS[i][j] = couple[j].num; //编号为i的发射站第j个匹配的接收站编号为rankS[i][j]
    }

    for (int i = 1; i <= C; i++)
    {
        for (int j = 1; j <= C; j++)
        {
            couple[j].num = j;
            couple[j].v = s[j].v;
            couple[j].dis = getDis(e[i], s[j]);
        }
        sort(couple + 1, couple + C + 1, cmp);
        for (int j = 1; j <= C; j++)
            rankE[i][couple[j].num] = j; //编号为i的接收站第rankE[i][j]个匹配的发射站编号为j
    }
}

//匹配所有发射站和接收站
void getMatch()
{
    memset(matchS, 0, sizeof(matchS));
    memset(matchE, 0, sizeof(matchE));
    for (int i = 1; i <= C; i++) //开始时所有发射站都准备匹配第一位的接收站
    {
        nextS[i] = 1;
    }
    int pos; //接收站序号
    bool flag = true; //是否还存在未匹配的发射站和接收站
    while (flag)
    {
        flag = false;
        for (int i = 1; i <= C; i++)
        {
            if (matchS[i] == 0) //发射站未匹配
            {
                flag = true;
                pos = rankS[i][nextS[i]];
                if (matchE[pos] == 0) //接收站未匹配
                {
                    matchE[pos] = i;
                    matchS[i] = pos;
                    nextS[i]++;
                }
                else //接收站已匹配
                {
                    if (rankE[pos][i] < rankE[pos][matchE[pos]])
                    {
                        matchS[matchE[pos]] = 0;
                        matchE[pos] = i;
                        matchS[i] = pos;
                        nextS[i]++;
                    }
                    else
                        nextS[i]++;
                }
            }
        }
    }
}

int main()
{
    int N;
    scanf("%d", &N);
    while (N--)
    {
        scanf("%d", &C);
        int num;
        for (int i = 1; i <= C; i++)
        {
            scanf("%d", &num);
            scanf("%d%lf%lf%lf", &s[num].v, &s[num].x, &s[num].y, &s[num].z);
        }
        for (int i = 1; i <= C; i++)
        {
            scanf("%d", &num);
            scanf("%d%lf%lf%lf", &e[num].v, &e[num].x, &e[num].y, &e[num].z);
        }

        getRank();
        getMatch();

        for (int i = 1; i <= C; i++)
            printf("%d %d\n", matchE[i], i);
        printf("\n");
    }
    return 0;
}

继续加油。

发布了326 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Intelligence1028/article/details/105317777
今日推荐