zoukankan      html  css  js  c++  java
  • [CF796D] Police Stations

    Description

    给定一棵树,树上有一些点是关键点。一棵树是合法的当且仅当所有点离最近的关键点的距离不超过 (d),求最多能删除多少条边。

    Solution

    考虑从所有的关键点开始 BFS。假设当前位于点 (p),下一个要访问的点是 (q),若 (q) 被访问过而 ((p,q)) 这条边未被访问过,则这条边可以被删除。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long 
    const int N = 1000005;
    
    int n;
    int k;                          // 关键点个数
    int d;                          // 距离限制
    int vis[N];                     // 点是否被访问过
    unordered_set <int> eVis;       // 边是否被访问过
    unordered_set <int> eSrc;       // E
    unordered_set <int> eAns;       // 可以删除的边的集合
    unordered_map <int,int> eInd;   // 边的序号
    vector <int> keyVertex;         // 关键点
    
    int edgeId(int u,int v)         // 获取边的编码
    {
        if(u>v) swap(u,v);
        return u*N+v;
    }
    
    void setEdgeVis(int u,int v) 
    {
        eVis.insert(edgeId(u,v));
    }
    
    int getEdgeVis(int u,int v)
    {
        if(eVis.find(edgeId(u,v))==eVis.end()) return false;
        return true;
    }
    
    vector <int> g[N];
    
    struct BFSData      // BFS 队列中的信息
    {
        int p;          // 当前点下标
        int dist;       // 到出发点的距离
    };
    
    void bfs()
    {
        queue <BFSData> que;
        for(auto p:keyVertex)
        {
            que.push({p,0});
            vis[p]=1;
        }
        while(!que.empty())
        {
            int p=que.front().p;
            int dist=que.front().dist;
            que.pop();
            if(dist==d) continue;
            for(auto q:g[p]) 
            {
                if(vis[q] && !getEdgeVis(p,q))
                {
                    eAns.insert(edgeId(p,q));
                }
                if(!vis[q])
                {
                    que.push({q,dist+1});
                    setEdgeVis(p,q);
                    vis[q]=1;
                }
            }
        }
    }
    
    signed main()
    {
        cin>>n>>k>>d;
        for(int i=1;i<=k;i++)
        {
            int tmp;
            cin>>tmp;
            keyVertex.push_back(tmp);
        }
        for(int i=1;i<n;i++)
        {
            int u,v;
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
            eInd[edgeId(u,v)]=i;
            eSrc.insert(edgeId(u,v));
        }
    
        bfs();
    
        for(auto i:eSrc)
        {
            if(eVis.find(i)==eVis.end()) 
            {
                eAns.insert(i);
            }
        }
    
        cout<<eAns.size()<<endl;
        for(auto i:eAns)
        {
            cout<<eInd[i]<<" ";
        }
        return 0;
    }
    
  • 相关阅读:
    js 小程序获取本周七天
    js 时间处理函数 获取今天的前几天和后几天的任意一天
    路由配置
    3 vue-router 的默认hash 改mode:history去除#号 传参
    Eslint 配置及规则说明(报错)
    打开左侧菜单栏
    sublime 对vue的高亮显示
    gitlab 本地建库配置 config
    GIT 安装
    v-html的应用
  • 原文地址:https://www.cnblogs.com/mollnn/p/13846794.html
Copyright © 2011-2022 走看看