題目鏈結
這個很考碼力……
寫得我………………
一般關於時間都有乙個隱含的最大值
然後又是最小時間
所以就是最大值最小,二分答案
二分出時間後
就讓每個軍隊盡量往上跳
跳不到根節點就停在那了
如果跳的到根節點,就記錄到根節點還能再跳多少,按照這個值排序
然後把還沒被控制的子樹記錄一下
然後按照距離排序
然後就貪心,就是讓路程剩餘值最小的去覆蓋子樹距離最小的,這樣不會浪費,
留下剩餘值大的去覆蓋子樹距離大的
注意這個時候如果子樹在該點跳到根節點的路徑時,就直接跳回去
一般題目是從條件出發,當達到題目要求的時候可以推出答案。
而二分答案就是從答案出發,利用條件來判斷看可不可以達到題目要求。
思維一定要換過來。
(1)寫遞迴函式的時候,不要下意識的寫dfs,比如這道題的push_up函式往下的時候我就寫成dfs了,而且我靜態差錯還沒查出來
(2)這道題可以設1的根節點為0,向上跳的時候注意判斷
(3)注意大於和不等於的區別
(4)判斷是否是葉子節點可以用乙個變數來表示,不需要記錄度數
(5)二分中的check函式因為要執行很多次所以要記得初始化
(6)寫結構體的時候記得內部加分號,每次都不加……
(7)這道題注意long long(不用也能過??)
#include#define rep(i, a, b) for(register int i = (a); i < (b); i++)#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using
namespace
std;
typedef
long
long
ll;const
int maxn = 5e5 + 10
;const
int maxm = 20
;struct edge;
edge e[maxn
<< 1
];int
head[maxn], tot;
ll dis[maxn][maxm + 5
];int f[maxn][maxm + 5
], st[maxn];
intvis[maxn], n, m, cnt;
void addedge(int
from, int to, intw);
head[
from] = tot++;
}void read(int&x)
while(isdigit(ch))
x *=f;
}void dfs(int u, int
fa)}
void push_up(int u, int
fa)
if(u != 1 && ok && p) vis[u] = 1;}
struct
node
};vector
v1;vector
v2;bool
check(ll ans)
); }
}push_up(
1, 0
);
for(int i = head[1]; ~i; i =e[i].next)
); }
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
int j = 0
; rep(i,
0, v1.size())
return
false;}
intmain()
dfs(
1, 0
); f[
1][0] = 0
; _for(j,
1, maxm)
_for(u,
1, n)
read(m);
_for(i,
1, m) read(st[i]);
if(m < cnt)
while(l + 1
printf(
"%d\n
", r);
return0;
}
NOIP2012 疫情控制
詳細的注釋已經寫到了 裡面。以後這種碼量多的最好都寫成函式再呼叫,確定好每個函式的作用。然後變數名最好也是有實際意義的qwq include include include include include define maxn 500010 using namespace std int n,m,...
NOIP 2012 疫情控制
題目鏈結 演算法 細心觀察發現 此題的答案具有單調性,也就是說,如果p小時能控制疫情,那麼q小時也能控制疫情 q p 因此我們可以二分答案,這是此題的突破口 問題就轉化為了檢驗 mid小時是否可以控制住疫情 我們發現,既然要求所有葉子節點得到管轄,那麼,軍隊所在的節點深度越淺,所能管轄的節點數就越多...
NOIP 2012 疫情控制
h 國有 n 個城市,這 n 個城市用 n 1 條雙向道路相互連通構成一棵樹,1 號城市是首都,也是樹中的根節點。h 國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境 城市 葉子節點所表示的城市 決定動用軍隊在一些城市建立檢查點,使得從首都到邊境 城市的每一條路徑上都至少有...