sgu 321 The Spy Network (dfs+贪心)

321. The Spy Network

Time limit per test: 0.5 second(s)
Memory limit: 65536 kilobytes

input: standard
output: standard

The network of spies consists of N intelligence officers. They are numbered with the code numbers from 1 to N so that nobody could discover them. The number 1 belongs to the radiowoman Kat. There is exactly N - 1 communication channels between the spies. It is known that a message from any spy to Kat can reach her. All channels are unidirectional.

A channel can have one of two types: protected and almost protected. It is known that a message will not be intercepted almost surely by the hostile security service if at least half of the channels along the path to radiowoman Kat are protected. What is the minimum number of channels to be made protected from almost protected, so that any message from any spy will not be intercepted almost surely ? What are those channels?

Input

The first line of the input contains the integer number N (1 ≤ N ≤ 200000). The following N - 1 lines contain the description of the communication channels. Each channel is described by a pair of the code numbers of spies (the direction of the channel is from the first spy to the second one) and the parameter pi. If pi =

protected

, the channel is protected and if pi =

almost protected

, the channel is almost protected.

Output

Write the number of channels to be converted to protected to the first line of the output. To the next line write numbers of channels to be made protected. If there are several solutions, choose any of them.

Example(s)

sample input
sample output
5
5 1 almost protected
3 1 almost protected
2 3 protected
4 3 almost protected
2
1 2

题意:一棵结点数为n的树,给出n-1条边,每条边有一个属性,0(almost protect)和1(protect),修改某些边的属性使得满足树上每一个结点到根节点的路径上,属性为1的边的数量大于等于属性为0的边的数量,求最小操作数

思路:首先要修改的边,应该离根节点越近越好,越近的话,对其他结点的贡献越多。所以用dfs(u)表示u的所有子节点中最多需要的1的边的数量,当这个数量大于u的深度的时候,就表示u前面全部修改了也不够满足条件,这时候就看u和下一个结点连接的边的属性是1还是0,是0的话,就要修改这条边,加进答案里面。dfs扫一遍就行了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <utility>
#include <queue>
#include <stack>
using namespace std;
const int INF=1<<30;
const double eps=1e-6;
const int N = 200010;

struct _edge{
    int u,v,next;
    bool w;
};
_edge e[N];
int first[N],n;
vector<int> ans;

int dfs(int u,int dep)
{
    int res = (dep+1)/2;
    for(int i=first[u];i!=-1;i=e[i].next)
    {
        int v = e[i].v;
        int tmp = dfs(v,dep+1);
        if(e[i].w) tmp--;
        else if(tmp>dep)
        {
            ans.push_back(i);
            tmp--;
        }
        res = max(res,tmp);
    }
    return res;
}

void run()
{
    int u,v;
    char s[20];
    memset(first,-1,sizeof(first));
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&v,&u);
        e[i].u = u;
        e[i].v = v;
        scanf("%s",s);
        if(s[0]==‘a‘)
            e[i].w=0,scanf("%s",s);
        else
            e[i].w=1;
        e[i].next = first[u];
        first[u] = i;
    }
//    for(int i=1;i<n;i++)
//        cout<<e[i].u << ‘ ‘ << e[i].v << ‘ ‘ << e[i].w<<endl;
    ans.clear();
    dfs(1,0);
    printf("%d\n",ans.size());
    if(!ans.empty()) printf("%d",ans[0]);
    for(int i=1;i<ans.size();i++)
        printf(" %d",ans[i]);
    puts("");
}

int main()
{
    freopen("case.txt","r",stdin);
    while(scanf("%d",&n)!=EOF)
        run();
    return 0;
}
时间: 2024-10-28 16:05:18

sgu 321 The Spy Network (dfs+贪心)的相关文章

SGU - 321 - The Spy Network

先上题目: 321. The Spy Network Time limit per test: 0.5 second(s)Memory limit: 65536 kilobytes input: standardoutput: standard The network of spies consists of N intelligence officers. They are numbered with the code numbers from 1 to N so that nobody co

【bzoj4813】[Cqoi2017]小Q的棋盘 dfs+贪心

题目描述 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V个格点,编号为0,1,2-,V-1,它们是连通的,也就是说棋子从任意格点出发,总能到达所有的格点.小Q在设计棋盘时,还保证棋子从一个格点移动到另外任一格点的路径是唯一的.小Q现在想知道,当棋子从格点0出发,移动N步最多能经过多少格点.格点可以重复经过多次,但不重复计数. 输入 第一行包含2个正整数V,N,其中V表示格点总数,N表示移动步数. 接下

E - Game 树上dfs贪心

https://vjudge.net/contest/299785#problem/E 题意:给你n个点,n-1个边构成有向数,同时每个点都有一个权值,现在给你k次操作,每次操作你必须从根节点1出发,然后走到一个叶节点结束然后将它们点的权值累加,同时走过的点的权值不可以重复计算,问你k次之后最大得到多大的值. 做法:我们倒着存边,两次dfs第一次求每个点到根节点的权值,然后将这个权值从大到小排序,第二次dfs贪心遍历每个从大到小排好序的节点,最后将得到的遍历结果再从大到小排序,取前k个数求和.

noip 2010 引水入城(dfs + 贪心)

非常感到抱歉,由于昨天有点忙,这道题的题解没写,今天补上,争取写的更加详细一点,让大家明白. 看一下题意: 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个NNN 行×M \times M×M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中. 因此,

UVA 1267 - Network(贪心DFS)

题目链接:点击打开链接 题意:一开始只有一个结点上有一个服务器, 为了让所有叶子结点距离服务器的距离不超过k, 我们在非叶子结点上添加服务器, 问最少添加多少服务器. 思路:贪心. 将第一个服务器所在结点作为根结点, 向下拓展, 记录父子关系, 将叶子结点的深度排序, 从最深的结点开始向上找k个距离的父节点, 安装服务器, 并进行一次DFS, 将所有距离它不超过k的结点标记. 细节参见代码: #include<cstdio> #include<cstring> #include&l

NOIP2010引水入城[BFS DFS 贪心]

题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施.水利设施有两种,分别为蓄水厂和输水站.蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中. 因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂.而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送.故一座城市能

Educational Codeforces Round 7 E. Ants in Leaves(DFS+贪心)

题目链接:点击打开链接 题意:给出一棵n个结点的树, 每个叶子结点上有一只蚂蚁, 每秒每只蚂蚁可以向相邻结点走一步, 同一时刻同一结点上只能有最多一只蚂蚁(根结点除外),根结点为1, 求所有蚂蚁都移动到1上的最小花费时间. 思路:很容易想到,采取贪心的思路就行了, 那么只要不断向上走就行了, 因为根结点比较特殊, 我们只考虑它的子树, 对于它的每一棵子树, 先dfs处理出所有结点的深度,然后对深度排序,  那么计算每个叶子结点到达根结点的时间.  假设第i个蚂蚁到达根结点的时间等于a[i],那么

SGU 321 知道了双端队列,

思路: 贪心, 每次删除最上面的边.. #include<utility> #include<iostream> #include<vector> #include<cstring> #include<deque> #include<cstdio> #include<algorithm> using namespace std; const int M = 200008; deque <int > q; vec

NOIP2015斗地主[DFS 贪心]

题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响.每一局游戏中,一副手牌由n张牌组成.游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利. 现在,牛牛只想知道,对于自己的若干