51nod 1299 監獄逃離

2021-08-16 03:53:23 字數 1365 閱讀 3667

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

首先這是一顆樹

為了方便,我們選擇乙個不是出口的地方作為根

不存在的情況只有乙個,那就是只有兩個點,特判就可以了

然後考慮怎麼構造答案

對於乙個點x,他是有犯人的

並且往兒子走,會走到出口,那麼我們必須把所有兒子封住

然後他就只能往上走了

對於乙個節點,如果他不是有犯人,但是兒子會有犯人走到他這裡,並且他的別的兒子有出口,那麼就把它封住

容易知道,這樣肯定是最優的

然後就沒有了。。

code:

#include

#include

#include

#include

using

namespace

std;

const

int n=100005;

int n,m;

struct qq

e[n*2];int num,last[n];

int d[n];

void init (int x,int y)

int rt;

bool ok[n];

int g[n];//有多少個

int h[n];//有多少個

int ans=0;

void dfs (int x,int fa)}}

if (ooo==false)//葉子

h[x]=1;

return ;

}if (g[x]==1)//堵死

for (int u=last[x];u!=-1;u=e[u].last)

if (g[x]!=0&&h[x]!=0)

}int main()

for (int u=1;uint x,y;

scanf("%d%d",&x,&y);x++;y++;

init(x,y);init(y,x);

}for (int u=1;u<=n;u++)

if (d[u]!=1)

// printf("%d\n",rt);

for (int u=1;u<=m;u++)

dfs(rt,0);

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

return

0;}

51Nod 1299 監獄逃離

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

51nod 1299 監獄逃離

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

51nod 1299 監獄逃離

1299 監獄逃離 基準時間限制 1 秒 空間限制 131072 kb 監獄有n條道路連線n 1個交點,編號0至n,整個監獄被這些道路連在一起 任何2點之間都有道路 人們通過道路在交點之間走來走去。其中的一些交點只有一條路連線,這些點是監獄的出口。在各個交點中有m個點住著犯人 m n 1 剩下的點可...