POJ 3084 Panic Room
生活随笔
收集整理的這篇文章主要介紹了
POJ 3084 Panic Room
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
POJ_3084
? ? 這個題目的題意感覺好費解,最后還是連蒙帶猜才搞懂的。首先題目中說的門大概是這樣的:可以是開著的也可以是鎖著的,如果是鎖著的也可以從門的某一側打開,但是另一側就沒法打開。圖中每個CP都對應了一個門,CP所在的房間就是能打開鎖著的門的那一側。
? ? 實際上我們就是要關閉一些門,使得從入侵者的位置開始(不妨標記為S)出發,不能夠到達要保護的房間(不妨標記為T)。對于任意一扇門來講,如果從能打開它的那一側走的話,顯然鎖上也是白搭的,而如果從另一側走的話,那么鎖和不鎖還是有區別的。于是不妨將一扇門看成兩條邊,一條是從能打開它的那一側走到另一側的邊,容量設為INF,另一條是反向的,容量設為1,這樣做S到T的最小割就是最后的解,因為這時可以將點分成兩部分,一部分是從S可以到達的,另一部分是可以到達T的,而且沒辦法從S這邊沿可走的邊(也就是非滿流的邊)走到T,這樣就相當于把T保護起來了。
#include<stdio.h> #include<string.h> #include<algorithm> #define MAXD 30 #define MAXM 1650 #define INF 0x3f3f3f3f int N, T, first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM]; int S, SS, d[MAXD], q[MAXD], work[MAXD]; void add(int x, int y, int z) {v[e] = y, flow[e] = z;next[e] = first[x], first[x] = e ++; } void init() {int i, j, k, n;char b[5];scanf("%d%d", &N, &T);SS = N, S = N + 1;memset(first, -1, sizeof(first[0]) * (N + 2)), e = 0;for(i = 0; i < N; i ++){scanf("%s", b);if(b[0] == 'I')add(SS, i, INF), add(i, SS, 0);scanf("%d", &n);for(j = 0; j < n; j ++){scanf("%d", &k);add(i, k, INF), add(k, i, 0);add(k, i, 1), add(i, k, 0); } }add(S, SS, INF); } int bfs() {int i, j, rear = 0;memset(d, -1, sizeof(d[0]) * (N + 2));d[S] = 0, q[rear ++] = S;for(i = 0; i < rear; i ++)for(j = first[q[i]]; j != -1; j = next[j])if(flow[j] && d[v[j]] == -1){d[v[j]] = d[q[i]] + 1, q[rear ++] = v[j];if(v[j] == T) return 1;}return 0; } int dfs(int cur, int a) {if(cur == T) return a;for(int &i = work[cur]; i != -1; i = next[i])if(flow[i] && d[v[i]] == d[cur] + 1)if(int t = dfs(v[i], std::min(a, flow[i]))){flow[i] -= t, flow[i ^ 1] += t;return t; }return 0; } int dinic() {int ans = 0, t;while(bfs()){memcpy(work, first, sizeof(first[0]) * (N + 2));while(t = dfs(S, INF))ans += t; }return ans; } void solve() {int ans = dinic();if(ans == INF)printf("PANIC ROOM BREACH\n");elseprintf("%d\n", ans); } int main() {int t;scanf("%d", &t);while(t --){init();solve();}return 0; } /* Sample Input:54 0 NI 1 1 NI 0 NI 2 1 3 I 04 0 NI 0 NI 1 0 NI 1 1 I 1 24 0 NI 2 1 2 NI 0 NI 2 1 3 I 04 0 NI 2 1 3 NI 0 NI 2 1 3 I 03 0 NI 1 2 NI 1 2 I 0Sample Output:1 PANIC ROOM BREACH 1 2 1*/
?
?
?
轉載于:https://www.cnblogs.com/staginner/archive/2012/08/17/2644365.html
總結
以上是生活随笔為你收集整理的POJ 3084 Panic Room的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么拦截触摸事件IOS
- 下一篇: SGU 185 Two shortest