24h購物| | PChome| 登入
2013-01-23 09:58:09| 人氣410| 回應0 | 上一篇 | 下一篇

[ZJ][DFS] d842. NOIP2003 4.传染病控制

推薦 0 收藏 0 轉貼0 訂閱站台


內容 :

    近来,一种新的传染病肆虐全球。蓬莱国也发现了零星感染者,为防止该病在蓬莱国

大范围流行,该国政府决定不惜一切代价控制传染病的蔓延。不幸的是,由于人们尚未完

全认识这种传染病,难以准确判别病毒携带者,更没有研制出疫苗以保护易感人群。于是,

蓬莱国的疾病控制中心决定采取切断传播途径的方法控制疾病传播。经过 WHO(世界卫

生组织)以及全球各国科研部门的努力,这种新兴传染病的传播途径和控制方法已经研究

消楚,剩下的任务就是由你协助蓬莱国疾控中心制定一个有效的控制办法。

 

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

    第一是它的传播途径是树型的,一个人X只可能被某个特定的人Y感染,只要Y

得病,或者是XY之间的传播途径被切断,则X就不会得病。

    第二是,这种疾病的传播有周期性,在一个疾病传播周期之内,传染病将只会感染一

代患者,而不会再传播给下一代。

    这些性质大大减轻了蓬莱国疾病防控的压力,并且他们已经得到了国内部分易感人群

的潜在传播途径图(一棵树)。但是,麻烦还没有结束。由于蓬莱国疾控中心人手不够,同

时也缺乏强大的技术,以致他们在一个疾病传播周期内,只能设法切断一条传播途径,而

没有被控制的传播途径就会引起更多的易感人群被感染(也就是与当前已经被感染的人有

传播途径相连,且连接途径没有被切断的人群)。当不可能有健康人被感染时,疾病就中止

传播。所以,蓬莱国疾控中心要制定出一个切断传播途径的顺序,以使尽量少的人被感染。

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

輸入說明 :

    输入格式的第一行是两个整数n1≤n≤300)和p。接下来p行,每一行有两个整数i

j,表示节点ij间有边相连(意即,第i人和第j人之间有传播途径相连)。其中节点

1是已经被感染的患者。

輸出說明 :

    只有一行,输出总共被感染的人数。

範例輸入 :

7 6
1 2
1 3
2 4
2 5
3 6
3 7

範例輸出 :

3

提示 :

出處 :

NOIP2003提高组第四题 (管理:liouzhou_101)
其實這題有個很詭異的地方,既然是一棵樹,其實不用給 p,給節點個數就好了。

接著找尋每一層有哪些節點,在每一層窮舉一個節點擋掉,直到某一層沒有任何節點可以繼續傳染。

不剪枝也會過。


/**********************************************************************************/
/*  Problem: d842 "NOIP2003 4.传染病控制" from NOIP2003提高组第四题    */
/*  Language: C (1271 Bytes)                                                      */
/*  Result: AC(10ms, 487KB) judge by this@ZeroJudge                               */
/*  Author: morris1028 at 2013-01-22 16:02:57                                     */
/**********************************************************************************/


#include <stdio.h>
int g[305][305], gt[305];
int tg[305][305], tgt[305], p[305];
int used[305];
int layer[305][305], lt[305] = {};
void make_root(int nd, int dep) {
    layer[dep][lt[dep]++] = nd;
    used[nd] = 1;
    int i;
    for(i = 0; i < gt[nd]; i++) {
        if(used[g[nd][i]] == 0) {
            tg[nd][tgt[nd]++] = g[nd][i];
            p[g[nd][i]] = nd;
            make_root(g[nd][i], dep+1);
        }
    }
}
int o[305], res = 0xffff;
void dfs(int dep, int sum) {
    int i, cnt = 0;
    for(i = 0; i < lt[dep]; i++) {
        if(o[p[layer[dep][i]]] == 1)
            o[layer[dep][i]] = 1;
        else
            cnt++, o[layer[dep][i]] = 0;
    }
    if(cnt == 0) {
        if(sum < res)
            res = sum;
        return;
    }
    if(sum >= res)   return;
    for(i = 0; i < lt[dep]; i++) {
        if(o[layer[dep][i]] == 0) {
            o[layer[dep][i]] = 1;
            dfs(dep+1, sum+cnt-1);
            o[layer[dep][i]] = 0;
        }
    }
}
int main() {
    int n, p, x, y;
    scanf("%d %d", &n, &p);
    while(p--) {
        scanf("%d %d", &x, &y);
        g[x][gt[x]++] = y;
        g[y][gt[y]++] = x;
    }
    make_root(1, 1);
    dfs(2, 1);
    printf("%d\n", res);
    return 0;
}

台長: Morris
人氣(410) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: ZeroJudge |
此分類下一篇:[ZJ][環狀DP] d836. NOIP2003 2.数字游戏
此分類上一篇:[ZJ][DFS剪枝] b153. NOIP2004 4.虫食算

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文