P1084 疫情控制

2022-05-29 04:42:11 字數 2992 閱讀 7865

p1084 疫情控制

hh 國有 nn個城市,這 n 個城市用n-1條雙向道路相互連通構成一棵樹,1號城市是首都,也是樹中的根節點。

hh國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境城市(葉子節點所表示的城市),決定動用軍隊在一些城市建立檢查點,使得從首都到邊境城市的每一條路徑上都至少有乙個檢查點,邊境城市也可以建立檢查點。但特別要注意的是,首都是不能建立檢查點的。

現在,在 hh 國的一些城市中已經駐紮有軍隊,且乙個城市可以駐紮多個軍隊。一支軍隊可以在有道路連線的城市間移動,並在除首都以外的任意乙個城市建立檢查點,且只能在乙個城市建立檢查點。一支軍隊經過一條道路從乙個城市移動到另乙個城市所需要的時間等於道路的長度(單位:小時)。

請問最少需要多少個小時才能控制疫情。注意:不同的軍隊可以同時移動。

輸入格式:

第一行乙個整數nn,表示城市個數。

接下來的 n-1n−1 行,每行33個整數,u,v,w,每兩個整數之間用乙個空格隔開,表示從城市 uu到城市vv 有一條長為 ww 的道路。資料保證輸入的是一棵樹,且根節點編號為 11。

接下來一行乙個整數 mm,表示軍隊個數。

接下來一行 mm個整數,每兩個整數之間用乙個空格隔開,分別表示這 mm 個軍隊所駐紮的城市的編號。

輸出格式:

乙個整數,表示控制疫情所需要的最少時間。如果無法控制疫情則輸出-1−1。

輸入樣例#1: 複製

4 

1 2 1

1 3 2

3 4 3

2 2 2

輸出樣例#1: 複製

3
【輸入輸出樣例說明】

第一支軍隊在 2號點設立檢查點,第二支軍隊從 2 號點移動到3號點設立檢查點,所需時間為 3 個小時。

【資料範圍】

保證軍隊不會駐紮在首都。

對於 20%的資料,2≤ n≤ 102≤n≤10;

對於 40%的資料,2 ≤n≤50,0

對於 60%的資料,2 ≤ n≤1000,0

對於 80%的資料,2 ≤ n≤10,000

對於 100%的資料,2≤m≤n≤50,000,0

noip 2012 提高組 第二天 第三題

題解:貪心+倍增,思維不難,但是**實現細節多,注意一種特殊情況,兒子中不一定要選乙個最小的點堵住他的祖先,有可能這棵子樹的所有兒子能力大都跑出去覆蓋別人的子樹,自己的祖先被旁邊乙個非常廢物的點覆蓋

#includeusing

namespace

std;

#define ll long long

const

int m = 50005, p = 20

;bool

fg[m], vis[m], ok[m];

int h[m], tot, anc[m][p+1

], n, t[m], top[m];

ll dis[m];

struct edgeg[m<<1

];void add(int u, int v, int

w)struct nodestk[m], sp[m], res[m];

bool cmp(node a, node b)

intch, m;

void dfs(int u, int f, int w, int

zx)}

intget(int u, int

f) }

if(!child) fg[u] = ok[u] != 0

;

return

fg[u];

}bool

check(ll k);

int pf = 0, tp = 0

;

for(int i = 1; i <= m; i++);continue

;}

if(dis[u] <=k) ;

if(!res[top[u]].id || res[top[u]].w >w);

}continue

; }

ll tmp =k;

for(int p = p; p >= 0 && tmp; p--)

if(dis[u] - dis[anc[u][p]] <=tmp)

tmp -= (dis[u] - dis[anc[u][p]]), u =anc[u][p];

ok[u] = 1

; }

get(1, 0

);

for(int i = h[1]; i; i =g[i].nxt)

sort(stk + 1, stk + 1 +tp, cmp);

if(pf > tp)return0;

sort(sp + 1, sp + 1 +pf, cmp);

int i = 1, j = 1

; vis[

0] = 1

;

while(j <=pf)

while(i <= tp && (vis[stk[i].id] || stk[i].w < sp[j].w))i++;

if(i > tp)return0;

vis[stk[i].id]=1

; i++;j++;

}return j >pf;

}int

main()

scanf("%d

", &m);

for(int i = 1; i <= m; i++)scanf("

%d", &t[i]);

dfs(

1, 0, 0, 0

); top[

1] = 0

;

if(ch >m)

ll lf = 0, rg = 500000, ans = -1

;

while(lf <=rg)

printf(

"%lld\n

", ans);

}

view code

P1084 疫情控制

p1084 疫情控制 好像二分 倍增 樹上差分是比較熱門的考尻點 會結合在一起考,難度比較大,需要多加練習。現在在解決noip最後的幾道大題,很鵝心。也沒有人做嚮導,很難受qwq 首先這是一棵樹,乙個軍隊肯定是越往上走越好。有大佬說過,對於這種提點的題,要是用倍增 要是時間最短,就是要是用時最長的軍...

P1084 疫情控制

p1084 傳送門 感覺noip t3也是有點東西的 將該題轉化為最大值最小問題後想到二分答案 接下來考慮 check 時如何貪心 由於除了在根節點所有軍隊都只往上跳明顯採取倍增的方式 記錄所有能到達根節點的軍隊和根節點下所有未被封死的子樹 將兩個序列從小到大排序後貪心匹配即可判斷 注意 在判斷封死...

洛谷P1084 (疫情控制)

h 國有 n 個城市,這 n 個城市用 n 1 條雙向道路相互連通構成一棵樹,1 號城市是首都,也是樹中的根節點。h 國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境城市 葉子節點所表示的城市 決定動用軍隊在一些城市建立檢查點,使得從首都到邊境城市 的每一條路徑上都至少有乙...