NOIP2012提高組 疫情控制

2022-05-19 10:10:53 字數 2062 閱讀 7272

題目:洛谷p1084、codevs1218、vijos p1783。

題目大意:有一棵n個節點的,根為1的帶權樹和m支軍隊。每支軍隊可以在乙個點上停下,那麼從1開始就不能經過這個點了。現在有m支軍隊已經在某些點上,移動一支軍隊到乙個相鄰的點所花時間等於該條邊的邊權。軍隊可同時移動。問至少多少時間才可以使從1開始都到不了任何乙個葉子節點(無法滿足條件輸出-1,根節點不能停軍隊)。

解題思路:首先,這道題是要求最少的時間,可以二分答案

然後是乙個貪心的思路:讓每支軍隊盡可能向根節點爬

因為軍隊越往上,能封住的葉子節點就越多(至少不會減少),那我們在能往上的情況下,盡可能往上。

一支軍隊如果不能到根節點,就讓其在能爬到的最高點停下,並封鎖這個節點。

如果能則記錄下它剩下的時間和它經過的《根節點的兒子》的編號(即它從哪個兒子過來的)。

然後我們dfs出已經被封鎖的節點,如果乙個節點的所有兒子都被封鎖,則該節點也算被封鎖。

之後我們把所有《沒被封鎖的,根節點的兒子》的編號和到根節點的距離記錄下來。

再然後,我們的任務就是把剛剛記錄的那些節點,用剩下的能到達根節點的軍隊去覆蓋

又是貪心,把節點按照到根節點的距離公升序排序,把軍隊按照剩餘時間公升序排序,然後對於乙個節點,用剩餘時間最少的,且比這個節點到根節點的距離大(因為要走過去)的軍隊覆蓋。

注意:如果乙個軍隊「經過的《根節點的兒子》」沒有被覆蓋,則優先覆蓋。

最後如果能成功覆蓋所有根節點的兒子,則說明答案可行,否則不可行。

對於讓軍隊向上爬的過程,我們可以用倍增的方法進行優化,所以要先預處理。

①預處理倍增。

②二分答案。

對於每個二分的答案:

①讓每個軍隊盡可能向上爬。對於不能到根節點的,讓其在能到達的最高節點停下,否則記錄下來。對記錄資料排序。

②找出所有未被封鎖的《根節點的兒子》記錄。對記錄資料排序。

③用剩餘軍隊覆蓋所有未被封鎖的根節點的兒子。判斷答案是否可行。

以下對時間複雜度分析:

預處理時間複雜度$o(n)$(dfs)+$o(n\log_2 n)$(處理倍增陣列)。

判斷答案時間複雜度$o(m\log_2 n)$(模擬軍隊上移)+$o(n)$(找未被封鎖的軍隊)+$o(n\log_2 n+m\log_2 n)$(排序)+$o(n+m)$(貪心,覆蓋未被封鎖的節點),這些都要乘上二分複雜度$o(\log_2 n)$。

故總時間複雜度$o((n+m)\log^2 n)$。

我不會告訴你我因為乙個逗號分隔符兩邊表示式寫反了而除錯了乙個半小時的

c++ code:

#include#include#include#includeusing namespace std;

#define n 50005

#define reg register

#define ll long long

int n,m,head[n],cnt,p[n],dep[n],f[n][17],cnta,cntb;

ll g[n][17];

bool vis[n];

struct nd;

}else vis[x]=true;

} feng(1);//搜尋已經被封的節點

if(vis[1])return true;

for(reg int i=head[1];i;i=e[i].nxt)

if(!vis[e[i].to])b[++cntb]=(nd);

if(cntacntb)return true;

if(a[i].num>=b[zz2].num)vis[b[zz2++].d]=true;

} while(vis[b[zz2].d]&&zz2<=cntb)++zz2;

} return zz2>cntb;

}int main()

printf("%lld\n",ans);

return 0;

}

NOIP2012提高組 疫情控制

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

NOIP2012 疫情控制

詳細的注釋已經寫到了 裡面。以後這種碼量多的最好都寫成函式再呼叫,確定好每個函式的作用。然後變數名最好也是有實際意義的qwq include include include include include define maxn 500010 using namespace std int n,m,...

NOIP 2012 疫情控制

題目鏈結 演算法 細心觀察發現 此題的答案具有單調性,也就是說,如果p小時能控制疫情,那麼q小時也能控制疫情 q p 因此我們可以二分答案,這是此題的突破口 問題就轉化為了檢驗 mid小時是否可以控制住疫情 我們發現,既然要求所有葉子節點得到管轄,那麼,軍隊所在的節點深度越淺,所能管轄的節點數就越多...