zoukankan      html  css  js  c++  java
  • P1041 传染病控制【暴搜】

    P1041 传染病控制

    提交 10.78k
    通过 3.74k
    时间限制 1.00s
    内存限制 125.00MB
    题目提供者 CCF_NOI
    历史分数100

    提交记录

    查看算法标签
    进入讨论版

    相关讨论

     
    查看讨论

    推荐题目

     
    查看推荐
     

    展开

    题目背景

    本题是错题,后来被证明没有靠谱的多项式复杂度的做法。测试数据非常的水,各种玄学做法都可以通过,不代表算法正确。因此本题题目和数据仅供参考。


    近来,一种新的传染病肆虐全球。蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范围流行,该国政府决定不惜一切代价控制传染病的蔓延。不幸的是,由于人们尚未完全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群。于是,蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播。经过 WHO(世界卫生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究清楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有效的控制办法。

    题目描述

    研究表明,这种传染病的传播具有两种很特殊的性质;

    第一是它的传播途径是树型的,一个人 XXX 只可能被某个特定的人 YYY 感染,只要 YYY 不得病,或者是 XYXYXY 之间的传播途径被切断,则 XXX 就不会得病。

    第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一代患者,而不会再传播给下一代。

    这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中心人手不够,同时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而没有被控制的传播途径就会引起更多的易感人群被感染(也就是与当前已经被感染的人有传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止传播。所以,蓬莱国疾控中心要制定出一个切断传播途径的顺序,以使尽量少的人被感染。

    你的程序要针对给定的树,找出合适的切断顺序。

    输入格式

    输入格式:
    第一行是两个整数 nnn 和 ppp。
    接下来 ppp 行,每一行有 222 个整数 iii 和 jjj,表示节点 iii 和 jjj 间有边相连。(意即,第 iii 人和第 jjj 人之间有传播途径相连)。其中节点 111 是已经被感染的患者。

    输出格式

    111 行,总共被感染的人数。

    输入输出样例

    输入 #1
    7 6
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    
    输出 #1
    3
    

    说明/提示

    对于 100%100\%100% 的数据,1≤n≤3001 leq n leq 3001n300。

    思路

      枚举可以砍的边,在砍的时候剪枝,对于一棵子树来说,如果砍掉一条边,则那条边下面的所有边都无法被访问到,在砍掉的同时标记其下所有的边,就可以避免重复枚举。

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 
      4 using namespace std;
      5 typedef long long LL;
      6 
      7 template<class T>inline void read(T &res)
      8 {
      9     char c;T flag=1;
     10     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     11     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     12 }
     13 
     14 namespace _buff {
     15     const size_t BUFF = 1 << 19;
     16     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     17     char getc() {
     18         if (ib == ie) {
     19             ib = ibuf;
     20             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     21         }
     22         return ib == ie ? -1 : *ib++;
     23     }
     24 }
     25 
     26 int qread() {
     27     using namespace _buff;
     28     int ret = 0;
     29     bool pos = true;
     30     char c = getc();
     31     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     32         assert(~c);
     33     }
     34     if (c == '-') {
     35         pos = false;
     36         c = getc();
     37     }
     38     for (; c >= '0' && c <= '9'; c = getc()) {
     39         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     40     }
     41     return pos ? ret : -ret;
     42 }
     43 
     44 const int maxn = 310;
     45 
     46 int n,m,ans;
     47 int cnt = 0;
     48 
     49 vector <int> level[maxn << 2];
     50 int sz[maxn];
     51 int edge[maxn <<2];
     52 int nxt[maxn << 2];
     53 int color[maxn << 2];
     54 int head[maxn << 2];
     55 
     56 void BuildGraph(int u, int v) {
     57     edge[cnt] = v;
     58     nxt[cnt] = head[u];
     59     head[u] = cnt++;
     60 }
     61 
     62 int dfs_level(int u, int depth, int pre) {
     63     //dbg(u);
     64     //dbg(depth);
     65     sz[u] = 1;
     66     for(int i = head[u]; ~i; i = nxt[i]) {
     67         int v = edge[i];
     68         //dbg(i),dbg(v);
     69         if(v == pre) {
     70             continue;
     71         }
     72         sz[u] += dfs_level(v, depth+1, u);
     73         level[depth].push_back(i);
     74     }
     75     return sz[u];
     76 }
     77 
     78 void dfs_draw(int u, int cl) {
     79     //dbg(u);
     80     color[u] = cl;
     81     int v = edge[u];
     82     for(int i = head[v]; ~i; i = nxt[i]) {
     83         //int v = edge[i].to;
     84         if(i == (u^1)) continue;
     85         dfs_draw(i,cl);
     86     }
     87 }
     88 
     89 void dfs(int u, int s) {
     90     //dbg(u);
     91     ans = min(ans, s);
     92     int d = level[u].size();
     93     for(int i = 0; i < d; ++i) {
     94         int v = level[u][i];
     95         if(!color[v]) {
     96             dfs_draw(v,1);
     97             dfs(u+1, s-sz[edge[v]]);
     98             dfs_draw(v,0);
     99         }
    100     }
    101 }
    102 
    103 int main()
    104 {
    105     scanf("%d %d",&n, &m);
    106     memset(head,-1,sizeof(head));
    107     ans = n;
    108     for(int i = 1; i <= m; ++i) {
    109         int u,v;
    110         scanf("%d %d",&u, &v);
    111         BuildGraph(u,v);
    112         BuildGraph(v,u);
    113     }
    114     dfs_level(1,0,-1);
    115     dfs(0,ans);
    116     cout << ans << endl;
    117     return 0;
    118 }
    View Code
  • 相关阅读:
    Android文件操作总结
    SQLite优化方法
    Android之TabHost布局
    Android简单数据存储SharedPreferences
    Android之SharedPreferences权限
    Android布局大全
    context理解
    Android网络连接之HttpURLConnection和HttpClient
    Android之ContentProvider总结
    Intent的简介以及属性详解
  • 原文地址:https://www.cnblogs.com/orangeko/p/12291638.html
Copyright © 2011-2022 走看看