ccf(csp) 认证 201403-4 无线网络 【bfs】

来源:互联网 发布:软件测评师试题 编辑:程序博客网 时间:2024/04/27 22:55

Problem:
有n个坐标已有路由器,有m个坐标可以放置路由器,但是最多放置k个,两路由器间距离不大于r即可建立链接,问最少使用多少个路由器?
Solution:
bfs的一种灵活应用,深度优先搜索是一种常用的编码思想,而不是一种编码套路,理解了思想,这道题也就很好ac了,求最短路,那么我们先确定了大体思路是bfs,但是问题关键在于k,我们在遍历过程中,当访问过(意味着已有更短路径)且中转路由器个数更多时,此时可以保证这个解一定是不是最优解,所以不放入队列中,否则有可能是最优解仍需要加入队列遍历。如果某刻路由器个数已经超过k,那么我们不把这个节点放入队列,认为这是一个不可行解。
note:
1. 有朋友反应网上有代码不考虑k可以ac,但显然代码是错误的,而网友也给出了一组很好的样例:
16 2 1 1
0 0
6 1
0 1
0 2
0 3
1 3
2 3
2 2
2 1
3 1
4 1
4 2
4 3
5 3
6 3
6 2
1 1
5 1
这个样例经过我笔算应该是10,而如果不考虑k会输出6,当然我的代码考虑了K后已经是正确结果10了,得分100分是代码正确的必要不充分条件。

2 . 我的代码是在原先已有错误的代码思路上加了一些细节改动而来, 我觉得这份代码的变量命名和结构已经有点惨不忍睹了,不过联系上我加的一些注释还是很好理解的。欢迎大家评论区继续讨论Orz

#include <iostream>#include <cstring>#include <queue>using namespace std;const int N = 100 + 100;int nn;//已有路由器的个数int k;//最多新增路由的个数struct {    long long x, y;} coord[N+1];struct node {    long long x, y;    int step, flag;};bool visited[N+1];int res[N+1];int bfs(int n, int begin, int end, long long r){    // 变量初始化    memset(visited, false, sizeof(visited));    // 设置根结点    node start, front, v;    start.x = coord[begin].x;    start.y = coord[begin].y;    start.step = 0;    start.flag = 0;//标识有几个新的路由器    queue<node> q;    q.push(start);    // 设置根结点为已经访问过    visited[begin] = true;    while(!q.empty()) {        front = q.front();        q.pop();        // 到达终点则结束        if(front.x == coord[end].x && front.y == coord[end].y)            return front.step - 1;        // 搜索可以连接的路由器        for(int i=0; i<n; i++) {            // 访问过的坐标则跳过            if(visited[i] && front.flag >= res[i])                continue;            // 判定下一个路由器的坐标是否在半径r之内, 不在半径之内则跳过,在半径之内则继续搜索            if((front.x - coord[i].x) * (front.x - coord[i].x) + (front.y - coord[i].y) * (front.y - coord[i].y) > r * r)                continue;            else {                // 第i个路由器设为已经访问过                visited[i] = true;                res[i] = front.flag;                // 计算步数,并且将第i个路由器加入队列                if(i >= nn)                    v.flag = front.flag+1;                else                    v.flag = front.flag;                v.x = coord[i].x;                v.y = coord[i].y;                v.step = front.step + 1;                if(v.flag <= k)                    q.push(v);            }        }    }    return 0;}int main(){    int m;    long long r;    // 输入数据    cin >> nn >> m >> k >> r;    for(int i=0; i<nn+m; i++)       // n个路由器的位置+可以增设的m个路由器的位置        cin >> coord[i].x >> coord[i].y;    // BFS    int ans = bfs(nn + m, 0, 1, r);    // 输出结果    cout << ans << endl;    return 0;}
1 0
原创粉丝点击