NOIP2012 疫情控制 二分答案 倍增

2021-08-30 13:39:57 字數 1827 閱讀 7148

傳送門:luogup1084

求最小值首先二分答案,記錄每個點倍增向上跳的資訊。

設當前二分答案為mid

midmi

d 跳不到根節點的軍隊的位置是唯一確定的。

對於跳的到的軍隊結點i

ii取出其到根後仍能多走的距離res

1=mi

d−di

s(1,

i)

res1=mid-dis(1,i)

res1=m

id−d

is(1

,i)。

同時d fs

dfsdf

s判斷根節點的兒子ch1

ich_

ch1i

​子樹中哪些子樹沒有被覆蓋完,同樣記錄距離為res

2=di

s(1,

ch1i

)res2=dis(1,ch_)

res2=d

is(1

,ch1

i​)

將r es

1,re

s2

res1,res2

res1,r

es2都按降序排序,貪心填充即可。

p.s.需要注意:對於某個沒有被覆蓋完的子樹x

xx,顯然由自己子樹中的走到根有閒餘的點來填充最優,所以列舉到x

xx時,先判斷x

xx子樹中有閒餘的且閒餘最小的點是否被用過,如果用過不能選再判斷當前res

1max

res1_

res1ma

x​是否可用。

#includeusing namespace std;

const int n=5e4+100;

typedef long long ll;

int n,m,d[n],loc[n],ban[n],p[n],ed[n],used[n];

int head[n],nxt[n<<1],to[n<<1],w[n<<1],tot;

ll dis[17][n],ans,val[n];int f[17][n],dr[n];

struct p;

bool operator<(const p&ky)const

inline void lk(int u,int v,int vv)

void dfs(int x)

}inline void upp(int id,ll lim)

if(lim>dis[0][x])else

}bool dfck(int x)

return false;

}inline bool ck(ll lim)

sort(bxd.begin(),bxd.end());

sort(dyd.begin(),dyd.end());

for(i=bxd.size()-1,j=dyd.size()-1;(~i) && (~j);--i)

for(;(~j) && used[dyd[j].id];--j);

if(j<0 || a.v>dyd[j].v) break;used[dyd[j].id]=1;

} if((~i)) re=false;

for(i=1;i<=m;++i) ban[loc[i]]=used[i]=0;

dyd.clear();bxd.clear();

for(i=head[1];i;i=nxt[i]) dr[to[i]]=0;

return re;

}int main()

if(ans>ori) ans=-1ll;

printf("%lld",ans);

return 0;

}

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 國的首都爆發了一種危害性極高的傳染病。當局為了控制疫情,不讓疫情擴散到邊境 城市 葉子節點所表示的城市 決定動用軍隊在一些城市建立檢查點,使得從首都到邊境 城市的每一條路徑上都至少有...