51nod 1299 監獄逃離(貪心)

2021-08-04 18:32:03 字數 1744 閱讀 5853

1299 監獄逃離

codility

基準時間限制:1 秒 空間限制:131072 kb 分值: 320 

難度:7級演算法題

監獄有n條道路連線n + 1個交點,編號0至n,整個監獄被這些道路連在一起(任何2點之間都有道路),人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人(m <= n + 1),剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯人所在的位置,問至少需要安排多少個警衛,才能保證沒有1個犯人能夠逃到出口,如果總有犯人能夠逃出去,輸出-1。

如上圖所示,點1,6 住著犯人,0,4,5,7,8是出口,至少需要安排4個警衛。

input

第1行:2個數n, m中間用空格分隔,n表示道路的數量,m表示犯人的數量(1<= n <= 100000, 0 <= m <= n + 1)。

之後n行:每行2個數s, e中間用空格分隔,表示點編號為s的點同編號為e的點之間有道路相連。(0 <= s, e <= n)。

之後的m行,每行1個數pi,表示編號為pi的點上有犯人。

output

輸出1個數對應最少需要多少警衛才能不讓犯人逃出監獄。
input示例

8 2

0 11 2

2 33 4

3 52 6

6 86 7

16

output示例

4
以任意乙個葉子節點作為根節點

mark[u]=0:以u為根的子樹的犯人能到達u,但不存在從u到葉子的路徑

mark[u]=1:以u為根的子樹中的犯人不能到達u,但存在從u到葉子的路徑

mark[u]=2:以u為根的子樹中的犯人不能到達u,且不存在從u到葉子的路徑

u有犯人,子節點不能存在通往葉子的路徑

u沒有犯人,如果子節點有犯人能到u且有路徑從子節點到葉子,封鎖u

根節點狀態為0,則封鎖根節點

#include#include#includeusing namespace std;

const int inf = 0x3f3f3f3f;

const int mx = 2e5 + 5;

struct edgee[mx*2];

int head[mx],tot;

int son[mx][3],mark[mx],p[mx],in[mx],ans;

void init()

void add(int u,int v)

void dfs(int u,int fa)

for(int i=head[u];~i;i=e[i].nxt)

//if(u==1) printf("%d\n",son[u][1]);

if(p[u]) ans+=son[u][1]; //有犯人,封鎖所有可以通往葉子的兒子

else if(son[u][0]&&son[u][1])

else if(son[u][0]) mark[u]=0;

else if(son[u][1]) mark[u]=1;

else mark[u]=2;

}int main()

int flag=1;

for(int i=1,u;i<=n;i++)

p[u]=1;

}if(flag)

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

}return 0;

}

51nod 1299 監獄逃離

監獄有n條道路連線n 1個交點,編號0至n,整個監獄被這些道路連在一起 任何2點之間都有道路 人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人 m n 1 剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯...

51Nod 1299 監獄逃離

這其實是一道樹形dp的神仙題。然後開始推推推,1 hour later樣例都過不了 然後仔細一看題目,貌似像乙個最小割模型,然後5min想了想建圖 首先拆點,將每個點拆成進和出兩個,然後連邊,邊權即為 1 表示割掉這條邊的代價 然後設超級源 s 讓 s 向所有犯人的出點 因為犯人的點無法割去 連邊,...

51nod 1299 監獄逃離

監獄有n條道路連線n 1個交點,編號0至n,整個監獄被這些道路連在一起 任何2點之間都有道路 人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人 m n 1 剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯...