CCF-CSP题解 201403-4 无线网络

新建不超过\(k\)个无线路由器,求使路由器1、2连通最少的中间路由器。

首先常规建图,将相距不超过\(r\)的路由器(包括新建的)相连。

想到了分层\(dijkstra\)。类似的,作\(bfs\)时记录已经经过的新建路由器个数\(b\)。\(queue\)内节点的形式就是当前路由器编号、经过的新建路由器个数、经过的路由器个数:\(<a,b,dis>\)。\(vis[a][b]\)数组可以不包括第三维\([dis]\),因为\(queue\)中的\(dis\)是递增的,再次到达\([a][b]\)的状态时,不会产生更好的结果。也可以加上,\(dis\)最多为100,200*100*100不会超时。

#include<bits/stdc++.h>
const int maxn = 100;
const int maxm = 100;

using namespace std;

int n, m, k;
double r;

struct tNode
{
    double x, y;
    int type;
};
tNode node[maxn + maxm + 10];

int to[(maxn + maxm) * (maxn + maxm) * 2 + 10];
int nex[(maxn + maxm) * (maxn + maxm) * 2 + 10];
int head[maxn + maxm + 10], cnt = 0;

void addEdge(int x, int y)
{
    to[cnt] = y; nex[cnt] = head[x]; head[x] = cnt++;
    to[cnt] = x; nex[cnt] = head[y]; head[y] = cnt++;
}

int vis[maxn + maxm + 10][maxm + 10];

struct tNNode
{
    int a, b, dis;
    tNNode(int aa, int bb, int ddis): a(aa), b(bb), dis(ddis){}
};

int main()
{
    scanf("%d%d%d%lf", &n, &m, &k, &r);

    for (int i = 1; i <= n + m; i++)
    {
        scanf("%lf%lf", &node[i].x, &node[i].y);
        node[i].type = (i <= n) ? 0 : 1;
    }

    memset(head, -1, sizeof(head));
    for (int i = 1; i <= n + m; i++)
    {
        for (int j = i + 1; j <= n + m; j++)
        {
            double dist = sqrt(pow((node[i].x - node[j].x), 2.0) + pow((node[i].y - node[j].y), 2.0));
            if (dist <= r)
                addEdge(i, j);
        }
    }

    memset(vis, 0, sizeof(vis));
    queue<tNNode> q;
    q.push(tNNode(1, 0, 0));
    vis[1][0] = 1;
    while (true)
    {
        tNNode x = q.front(); q.pop();
        int a = x.a, b = x.b, dis = x.dis;
        if (a == 2)
        {
            printf("%d\n", dis - 1);
            break;
        }
        for (int i = head[a]; i != -1; i = nex[i])
        {
            int l = to[i];
            if (node[l].type == 0)
            {
                if (!vis[l][b])
                {
                    q.push(tNNode(l, b, dis + 1));
                    vis[l][b] = 1;
                }
            }
            else
            {
                if (b < k && !vis[l][b + 1])
                {
                    q.push(tNNode(l, b + 1, dis + 1));
                    vis[l][b + 1] = 1;
                }
            }
        }
    }

    return 0;
}
上一篇:HackThisSite(Basic missions level1-11)攻略


下一篇:CCF CSP认证201403-3 命令行选项