zoukankan      html  css  js  c++  java
  • SGU

    先上题目:

    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
    

        题意:给你一棵树,树的边是有向的,每条边有一个状态0或者1,现在告诉你根是1,问你最少需要改变多少多少条边的状态才能使每个点到达跟的路径上有一半以上的边是1,并且输出数目和这些边的编号。

        做法:先从根节点dfs一次,对于记录下每个节点还需要多少个1以及这个节点以及它的子树中的节点最多需要1的节点需要1的数目。然后在从根节点再dfs一次,这次的目的是对于当前状态为0的边我们可以考虑是否将它转化为1,因为对于这种转化来说,转移深度小的边对树的影响比转移深度大的边对树的影响更大,所以我们如果一棵子树里面的节点还需要1的话,就转换深度小的边。也就是说这样做符合贪心的思想。

    上代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define MAX 200002
     5 using namespace std;
     6 
     7 typedef struct {
     8     int id,u,v,w,next;
     9 } Edge;
    10 
    11 Edge e[MAX];
    12 char ch[100];
    13 int p[MAX],need[MAX],am[MAX];
    14 int tot,top;
    15 
    16 inline void add(int id,int u,int v,int w) {
    17     e[tot].id=id;
    18     e[tot].u=u;
    19     e[tot].v=v;
    20     e[tot].w=w;
    21     e[tot].next=p[u];
    22     p[u]=tot++;
    23 }
    24 
    25 void dfs1(int r,int dep,int a) {
    26     am[r]=(dep+1)/2 - a;
    27     for(int i=p[r]; i!=-1; i=e[i].next) {
    28         dfs1(e[i].v,dep+1,a+e[i].w);
    29         am[r]=max(am[e[i].v],am[r]);
    30     }
    31 }
    32 
    33 void dfs2(int r,int num) {
    34     for(int i=p[r]; i!=-1; i=e[i].next) {
    35         if(num<am[e[i].v]) {
    36             if(e[i].w==0) {
    37                 need[top++]=e[i].id;
    38                 dfs2(e[i].v,num+1);
    39             } else dfs2(e[i].v,num);
    40         }
    41     }
    42 }
    43 
    44 int main() {
    45     int n,u,v;
    46     //freopen("data.txt","r",stdin);
    47     while(~scanf("%d",&n)) {
    48         memset(p,-1,sizeof(p));
    49         tot=top=0;
    50         for(int i=1; i<n; i++) {
    51             scanf("%d %d %s",&v,&u,ch);
    52             if(ch[0]=='a') {
    53                 scanf("%s",ch);
    54                 add(i,u,v,0);
    55             } else {
    56                 add(i,u,v,1);
    57             }
    58         }
    59         dfs1(1,0,0);
    60         dfs2(1,0);
    61         printf("%d
    ",top);
    62         for(int i=0; i<top; i++) {
    63             if(i) printf(" ");
    64             printf("%d",need[i]);
    65         }
    66         printf("
    ");
    67     }
    68     return 0;
    69 }
    /*321*/
  • 相关阅读:
    可空类型转换为不可空的普通类型
    如何使用AspNetPager分页控件和ObjectDataSource控件进行分页
    TFS映射后丢失引用的问题
    (很好用)JS时间控件实现日期的多选
    取两个日期之间的非工作日的天数(指的是周六、周日)
    在日期格式化的时候提示错误:Tostring没有采用一个参数的重载
    Linq返回的集合类型不是已有的表格类型时的写法(谨记:列表的时候用)
    系统缓存全解析6:数据库缓存依赖
    实现文本框动态限制字数的实现(好方法)
    实现GridView内容循环滚动
  • 原文地址:https://www.cnblogs.com/sineatos/p/3936030.html
Copyright © 2011-2022 走看看