h國有 n個城市,這 n 個城市用n−1條雙向道路相互連通構成一棵樹,1號城市是首都,也是樹中的根節點。
h國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境城市(葉子節點所表示的城市),決定動用軍隊在一些城市建立檢查點,使得從首都到邊境城市的每一條路徑上都至少有乙個檢查點,邊境城市也可以建立檢查點。但特別要注意的是,首都是不能建立檢查點的。
現在,在 h國的一些城市中已經駐紮有軍隊,且乙個城市可以駐紮多個軍隊。一支軍隊可以在有道路連線的城市間移動,並在除首都以外的任意乙個城市建立檢查點,且只能在乙個城市建立檢查點。一支軍隊經過一條道路從乙個城市移動到另乙個城市所需要的時間等於道路的長度(單位:小時)。
請問最少需要多少個小時才能控制疫情。注意:不同的軍隊可以同時移動。
輸入格式:
第一行乙個整數n,表示城市個數。
接下來的 n−1 行,每行3個整數,u,v,w,每兩個整數之間用乙個空格隔開,表示從城市 u到城市v 有一條長為 w的道路。資料保證輸入的是一棵樹,且根節點編號為 1。
接下來一行乙個整數 m,表示軍隊個數。
接下來一行 m個整數,每兩個整數之間用乙個空格隔開,分別表示這 m 個軍隊所駐紮的城市的編號。
輸出格式:
乙個整數,表示控制疫情所需要的最少時間。如果無法控制疫情則輸出−1。
輸入樣例#1: 複製
41 2 1
1 3 2
3 4 3
2 2 2
輸出樣例#1: 複製
3
【輸入輸出樣例說明】
第一支軍隊在 2號點設立檢查點,第二支軍隊從 2 號點移動到3 號點設立檢查點,所需時間為 3個小時。
【資料範圍】
保證軍隊不會駐紮在首都。
對於 20%的資料,2≤n≤10;
對於 40%的資料,2≤n≤50,0對於 60%的資料,2≤n≤1000,0對於 80%的資料,2≤n≤10,000;
對於 100%的資料,2≤m≤n≤50,000,0noip 2012 提高組 第二天 第三題
solution
感天動地!!終於調出來了!!想是好想,**實現細節好多aaaaa!!!!qaq
二分答案,check中間將軍隊倍增貪心向上跳,如果可以跳到根節點,那麼剩下還可以跳的值意味著它可以轉移到根節點的其它兒子去,如果不能跳到根節點意味著它必須固定在能跳到的最高位置,打標記。
統計標記,如果子樹全都有標記那麼它也有標記。
統計哪些根節點的兒子沒有被標記,這些節點就有可能從之前統計的可以轉移出來的這些點移過來。
所以排序後雙指標掃瞄,如果在統計標記後原來的位置都還沒有被打標記,那麼這個位置就不能移出去了,不然如果滿足移出去的路徑長度,那麼就給移出去的位置打標記。
錯的好慘:
for(int p = 20; p >= 0; p --)if(l + len[u][p] <= mid && jum[u][p] != 0)
l += len[u][p], u = jum[u][p];
這裡應該先更新長度再跳,之前一直先跳再更新qaq
#include#define ll long longusing
namespace
std;
intread()
struct
node edge[
500005
];int h[50005
], stot;
void add(int u, int v, int
w) ;
h[u] =stot;
}int
n, m;
int jum[50005][21
];ll len[
50005][21], dis[50005
];void dfs(int u, int
f) }
int tag[50005
];void get_tag(int u, int
f)
if(p && d && u != 1) tag[u] = 1;}
int pos[50005
];struct
point p[
50005], q[50005
];bool cmp(point a, point b)
bool check(int
mid)
}get_tag(
1, 0
);
for(int i = h[1]; i; i =edge[i].nex)
sort(q + 1, q + 1 + sb, cmp); sort(p + 1, p + 1 +sd, cmp);
int l = 1
;
for(int i = 1; i <= sb; i ++)
return l >sd;
}ll sum;
ll erfen()
return
ans;
}int
main()
m =read();
int tmp = 0
;
for(int i = h[1]; i; i = edge[i].nex) tmp ++;
if(tmp >m)
dfs(
1, 0
);
for(int i = 1; i <= n; i ++) sum +=dis[i];
for(int i = 1; i <= m; i ++) pos[i] =read();
ll ans =erfen();
printf(
"%lld
", ans);
return0;
}
P1084 疫情控制(二分答案,倍增,貪心)
p1084 疫情控制 給定一棵樹,一些點 不包括樹根 上有軍隊,每條邊有乙個邊權 移動時間 各個軍隊可以同時移動,求最小的移動時間,使得每條通往任意葉子結點的路徑上至少都有一支軍隊.二分答案 通過觀察題意可知,答案具有單調性 如果p pp小時時能控制所有的邊境城市,那麼q q p q q p q q...
疫情控制(二分 貪心 倍增)
noip 2012 提高組 第二天 第三題 題目描述 h 國有 n 個城市,這 n 個城市用 n 1 條雙向道路相互連通構成一棵樹,1 號城市是首都,也是樹中的根節點。h 國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境 城市 葉子節點所表示的城市 決定動用軍隊在一些城市建...
洛谷P1084 (疫情控制)
h 國有 n 個城市,這 n 個城市用 n 1 條雙向道路相互連通構成一棵樹,1 號城市是首都,也是樹中的根節點。h 國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境城市 葉子節點所表示的城市 決定動用軍隊在一些城市建立檢查點,使得從首都到邊境城市 的每一條路徑上都至少有乙...