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