51nod 1299 監獄逃離

2022-08-17 03:57:27 字數 1867 閱讀 9857

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

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

第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的點上有犯人。

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

0 11 2

2 33 4

3 52 6

6 86 7

16

4
典型的一道樹形dp,聽說有人跑20萬網路流過了orz

使得任意乙個出口為根節點,逃離方向就固定為向上到根或向下到葉子節點

考慮乙個點的3種狀態:

f[i],表示以i為根的子樹的狀態

f[i]=0,子樹中的點無法到達這個點,且不存在一條從這點到葉子節點的路徑。 

f[i]=1,子樹中的點無法到達這個點,但存在一條從這點到葉子節點的路徑。 

f[i]=2,子樹中的點可以到達這個點,且不存在一條從這點到葉子節點的路徑

i點的兒子的狀態都為0,則f[i]=0

兒子的狀態有1也有2,則i點必須放,ans++(以為2點可以通過i點到葉子節點)

若i有逃犯則兒子中有1狀態的都要被放,ans加上兒子為1的個數

剩下的兒子狀態單一,直接轉移即可。

1 #include2 #include3 #include4 #include5

#define fo(i,a,b) for(int i=a;i<=b;i++)

6#define fd(i,a,b) for(int i=a;i>=b;i--)

7#define fh(i,x) for(int i=head[x];i;i=next[i])

8 typedef long

long

ll;9

using

namespace

std;

10 inline int max(int x,int y)

11 inline int min(int x,int y)

12 inline int

read()

17const

int n=1e5+5;18

intn,m,tot,x,y,ans,d[n],f[n];

19int to[n*2],next[n*2

],head[n];

20bool

bz[n];

21void add(int x,int y)

22void dfs(int x,int

y) 31

intmain()

38 bz[x]=1;39

}40int root=1

;41 fo(i,1,n) if(d[i]==1)

42 dfs(root,0

);43

if(f[root]==2) ans++;

44 printf("

%d\n

",ans);

45 }

51nod 1299 監獄逃離

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

51Nod 1299 監獄逃離

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

51nod 1299 監獄逃離

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