CodeForces 796D bfs

CodeForces 796D

题意:n个城市,k个警察局,n-1条边连成树,所有边长都为1,给定的图满足规则:任一城市到离它最近的警察局距离不超过d。 问你最多可以删掉多少条边,使得依旧满足规则。

tags:从所有警察局开始一起bfs,这样当要走向一个点to的时候,肯定是离警察局最近的路。如果to没有走过,就说明这条边 i 是需要的,标记它。最后没有被标记到的边就是不需要的。  注意坑点:d 可以为0

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,b,a) for (int i=b;i>=a;i--)
#define mes(a,b)  memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define MP make_pair
#define PB push_back
#define fi  first
#define se  second
typedef long long ll;
const int N = 300005, M = N<<1;

int n, k, d, pli[N], mp[M], ans;
bool mark[M], vis[N], vise[M];
struct Edge { int to, next; } e[M];
int tot, head[N];
void Addedge(int u, int v, int x)
{
    e[tot]={v, head[u]}, mp[tot]=x, head[u]=tot++;
    e[tot]={u, head[v]}, mp[tot]=x, head[v]=tot++;
}
queue<int > q;
int q1[N], sz;
void bfs()
{
    rep(ca,1,d)
    {
        sz=0;
        while(!q.empty()) { q1[++sz]=q.front(); q.pop(); }
        rep(cb,1,sz)
        {
            int u=q1[cb];
            for(int i=head[u]; i!=-1; i=e[i].next)
                if(vise[mp[i]]==false)
            {
                vise[mp[i]]=true;
                int to=e[i].to;
                if(vis[to]==false) {
                    q.push(to), vis[to]=true, mark[mp[i]]=true;
                }
            }
        }
    }
}
void Init()
{
    tot=0;  ans=0;
    mes(head, -1);
    mes(mark, false);
    mes(vis, false);
    mes(vise, false);
}
int main()
{
    scanf("%d %d %d", &n, &k, &d);
    Init();
    rep(i,1,k)
    {
        scanf("%d", &pli[i]);
        vis[pli[i]]=true, q.push(pli[i]);
    }
    int u, v;
    rep(i,1,n-1)
    {
        scanf("%d %d", &u, &v);
        Addedge(u, v, i);
    }
    if(d==0)
    {
        printf("%d\n", n-1);
        rep(i,1,n-1) printf("%d ", i);
        return 0;
    }
    bfs();
    rep(i,1,n-1) if(mark[i]==false) ++ans;
    printf("%d\n", ans);
    rep(i,1,n-1) if(mark[i]==false) printf("%d ", i);

    return 0;
}
时间: 2024-08-23 09:04:43

CodeForces 796D bfs的相关文章

CodeForces 789E bfs建模,思维

CodeForces 789E 题意:有k种可乐,每种的测试为ai/1000. 要你合成一种浓度为n/1000的可乐,问最小要杯可乐,每种可乐可重复取. tags:  要注意到浓度绝不会超过1000/1000. 假设选取m杯可乐,则 (a1+a2+......+am) / m = n,变换一下为(a1-n)+(a2-n)+......+(am-n) = 0.即要选 m杯可乐,其浓度减 n之和为0.而浓度不超过1000,故(a1-n)+(a2-n)+....+(as-n)的和肯定在 -1000~1

796D(bfs)

题目链接: http://codeforces.com/problemset/problem/796/D 题意: 给出一颗 n 个节点树, 树枝连接的两个定点距离为 1, 树中有 k 个特殊点, 问最多可以删除哪些树枝, 使得树中其他顶点到特殊点的最小距离不大于 d. 注意: 题目说明了一定有解. 思路: bfs 可以直接 bfs 求其他点到特殊点的最短距离, 因为题目说明给出的数据都是有解的, 即所有顶点到特殊点的距离都是不大于 d 的. 那么搜完所有顶点后剩余的边就是不必要的.  即答案中的

codeforces 590C:(BFS)

建道路使得三个国家联通,问最少需要在多少个格子上修路 枚举每一个格子,计算三个国家到达这个格子的最短路,取最小的 发现pair用来代替node有时候还是很好用的 #include"cstdio" #include"queue" #include"cmath" #include"stack" #include"iostream" #include"algorithm" #include&q

Codeforces Gym 100187E E. Two Labyrinths bfs

E. Two Labyrinths Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/E Description A labyrinth is the rectangular grid, each of the cells of which is either free or wall, and it's possible to move only between free

Codeforces 788C The Great Mixing(背包问题建模+bitset优化或BFS)

[题目链接] http://codeforces.com/problemset/problem/788/C [题目大意] 给出一些浓度的饮料,要求调出n/1000浓度的饮料,问最少需要多少升饮料 [题解] 设浓度为a,现在要求出系数x1,x2,x3……,使得x1*a1+x2*a2+x3*a3+……=n*(x1+x2+x3+……) 得a1*(x1-n)+a2*(x2-n)+a3*(x3-n)+……=0 假设现在有x1-n和x2-n,设其数值为x和y,那么一定有(x)*y+(-y)*x=0, x+y

Educational Codeforces Round 1(D. Igor In the Museum) (BFS+离线访问)

题目链接:http://codeforces.com/problemset/problem/598/D 题意是 给你一张行为n宽为m的图 k个询问点 ,求每个寻问点所在的封闭的一个上下左右连接的块所能看到的壁画有多少(大概这样吧). 我的做法是bfs(dfs也可以)这个为'.'的点,要是遇到上下左右其中有'*'的话就加起来.要是每次询问然后bfs一下肯定超时,所以我用一个ans[1005][1005]记录每个点的值,ok[1005][1005]数组判断是否访问过,初始化为false.然后开始遍历

BFS Codeforces Round #297 (Div. 2) D. Arthur and Walls

题目传送门 1 /* 2 题意:问最少替换'*'为'.',使得'.'连通的都是矩形 3 BFS:搜索想法很奇妙,先把'.'的入队,然后对于每个'.'八个方向寻找 4 在2*2的方格里,若只有一个是'*',那么它一定要被替换掉 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <queue> 1

Codeforces 467D Fedor and Essay(bfs)

题目链接:Codeforces 467D Fedor and Essay 题目大意:给定一个含n个单词的文本,然后给定m种变换,要求变换后r的个数尽量少,长度尽量短,不区分大小写. 解题思路:bfs,将每个单词处理成长度以及r的个数,然后从最优的开始更新即可,类似dp. #include <cstdio> #include <cstring> #include <map> #include <string> #include <vector> #

Codeforces 429B Working out bfs构造

题目链接:点击打开链接 题意:给定n*m的矩阵 有一个人a从左上角走到右下角,只能↓或→走 另一个人b从左下角走到右上角,只能↑或→走 使得2个人的路径有且仅有一个格子是相交的. 统计2个人的权值和(相交格子的权值和不计) 问最大的权值和是多少. 思路: 首先转换一下题意,也就是找一个格子与4个角落连不相交的线. 我们观察相交的那个格子,那个格子的上下左右必然对应着一个角落. (i,j)点,那么(i-1,j)必然对应左上角或右上角的其中一个角落. 这样(i,j)点的4个相邻格子各自对应一个角落(