監獄逃離 51nod1299 最小割

2021-08-13 05:20:07 字數 1370 閱讀 8557

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

在olahiuj的安利下做了這題。

正解應該是樹形dp之類的東東。。。

但是我們也可以用最小割寫。。。(不知為何10^5的資料dinic居然能過)

建圖:

1.如果i和j有邊相連(i,j』,∞)(j,i』,∞)

2.如果i有犯人(s,i,∞)

3.如果i是出口(i,t,∞)

4.把i點拆成入點和出點(i』,i,1)

#include

#include

#include

#include

#include

using

namespace

std;

struct arredge[2000000];

int ls[410000],cur[410000];

int f[2100000];

int edge_m=1;

int n,m,s,t;

int ans,num=0;

void add(int x,int y,int w)

; cur[y]=ls[x]=edge_m; f[edge_m]=w;

edge[++edge_m]=(arr); cur[y]=ls[y]=edge_m; f[edge_m]=0;

}int dis[400000];

bool bfs()

}}while (!q.empty());

return

false;

}int find(int x,int min_)

}if (rec==min_) dis[x]=-1;

return min_-rec;

}int dinic()

}int a[410000];

int du[410000];

int main()

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

n++;

s=n*2+1; t=n*2+2;

for (int i=0;i<=n;i++)

dinic();

if (ans==410000) printf("-1");

else

printf("%d",ans);

}

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 剩下的點可以安排警衛,有警衛把守的地方犯人無法通過。給出整個監獄的道路情況,以及犯...