監獄有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 剩下的點可...