24h購物| | PChome| 登入
2013-04-02 10:22:56| 人氣872| 回應0 | 上一篇 | 下一篇

[UVA][maxflow] 563 - Crimewave

推薦 0 收藏 0 轉貼0 訂閱站台


  Crimewave 

Nieuw Knollendam is a very modern town. This becomes clear already when looking at the layout of its map, which is just a rectangular grid of streets and avenues. Being an important trade centre, Nieuw Knollendam also has a lot of banks. Almost on every crossing a bank is found (although there are never two banks at the same crossing). Unfortunately this has attracted a lot of criminals. Bank hold-ups are quite common, and often on one day several banks are robbed. This has grown into a problem, not only to the banks, but to the criminals as well. After robbing a bank the robber tries to leave the town as soon as possible, most of the times chased at high speed by the police. Sometimes two running criminals pass the same crossing, causing several risks: collisions, crowds of police at one place and a larger risk to be caught.


To prevent these unpleasant situations the robbers agreed to consult together. Every Saturday night they meet and make a schedule for the week to come: who is going to rob which bank on which day? For every day they try to plan the get-away routes, such that no two routes use the same crossing. Sometimes they do not succeed in planning the routes according to this condition, although they believe that such a planning should exist.


Given a grid of $(s times a)$ and the crossings where the banks to be robbed are located, find out whether or not it is possible to plan a get-away route from every robbed bank to the city-bounds, without using a crossing more than once.

Input 

The first line of the input contains the number of problems p to be solved.

  • The first line of every problem contains the number s of streets ( $1 le s le 50$), followed by the number a of avenues ( $1 le a le 50$), followed by the number b ($b ge 1$) of banks to be robbed.

  • Then b lines follow, each containing the location of a bank in the form of two numbers x (the number of the street) and y (the number of the avenue). Evidently $1 le x le s$ and $1 le y le a$.

Output 

The output file consists of p lines. Each line contains the text possible or not possible. If it is possible to plan non-crossing get-away routes, this line should contain the word: possible. If this is not possible, the line should contain the words not possible.

Sample Input 

2
6 6 10
4 1
3 2
4 2
5 2
3 4
4 4
5 4
3 6
4 6
5 6
5 5 5
3 2
2 3
3 3
4 3
3 4

Sample Output 

possible
not possible



Miguel A. Revilla
1998-03-10

設一個源點 0, 匯點 2*n*m+1, 然後平面上每個點都拆成 in, out 兩點,
然後源點連向需要的 in 點, 邊緣的 out 點連向匯點, 每個點out的四方連向那個點的in.

如果 maxflow == b 則 possible, 反之則否.

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
struct Node {
    int x, y, v;// x->y, v
    int next;
} edge[500005];
int e, head[50000], dis[50000], prev[50000], record[50000];
void addEdge(int x, int y, int v) {
    edge[e].x = x, edge[e].y = y, edge[e].v = v;
    edge[e].next = head[x], head[x] = e++;
    edge[e].x = y, edge[e].y = x, edge[e].v = 0;
    edge[e].next = head[y], head[y] = e++;
}
int maxflow(int s, int t) {
    int flow = 0;
    int i, j, x, y;
    while(1) {
        memset(dis, 0, sizeof(dis));
        dis[s] =  0xffff; // oo
        queue<int> Q;
        Q.push(s);
        while(!Q.empty()) {
            x = Q.front();
            Q.pop();
            for(i = head[x]; i != -1; i = edge[i].next) {
                y = edge[i].y;
                if(dis[y] == 0 && edge[i].v > 0) {
                    prev[y] = x, record[y] = i;
                    dis[y] = min(dis[x], edge[i].v);
                    Q.push(y);
                }
            }

        }
        if(dis[t] == 0) break;
        flow += dis[t];
        for(x = t; x != s; x = prev[x]) {
            int ri = record[x];
            edge[ri].v -= dis[t];
            edge[ri^1].v += dis[t];
        }
    }
    return flow;
}
int main() {
    int testcase;
    int n, m, b, x, y;
    int i, j, k;
    scanf("%d", &testcase);
    while(testcase--) {
        scanf("%d %d %d", &n, &m, &b);
        e = 0;
        memset(head, -1, sizeof(head));
        int dirx[4] = {1,-1,0,0};
        int diry[4] = {0,0,1,-1};
        for(i = 0; i < n; i++) {
            for(j = 0; j < m; j++) {
                int innode = i*m+j+1, outnode = i*m+j+1+n*m;
                addEdge(innode, outnode, 1);
                for(k = 0; k < 4; k++) {
                    x = i+dirx[k], y = j+diry[k];
                    if(x < 0 || y < 0 || x >= n || y >= m)
                        continue;
                    int y_innode = x*m+y+1;
                    addEdge(outnode, y_innode, 0xffff);
                }
            }
        }
        for(i = 0; i < b; i++) {
            scanf("%d %d", &x, &y);
            x--, y--;
            int node = x*m + y + 1;
            addEdge(0, node, 1);
        }
        for(i = 0; i < n; i++) {
            int outnode = i*m+1+n*m;// g[i][0]
            addEdge(outnode, 2*n*m+1, 1);
            outnode = i*m+m-1+1+n*m;// g[i][m-1]
            addEdge(outnode, 2*n*m+1, 1);
        }
        for(i = 1; i < m-1; i++) {
            int outnode = i+1+n*m;// g[0][i]
            addEdge(outnode, 2*n*m+1, 1);
            outnode = (n-1)*m+i+1+n*m;// g[n-1][i]
            addEdge(outnode, 2*n*m+1, 1);
        }
        int flow = maxflow(0, 2*n*m+1);
        if(flow == b)
            puts("possible");
        else
            puts("not possible");
    }
    return 0;
}
/*
n*m, node(g[i][j])
g[i][j] innode : i*m+j+1, outnode : i*m+j+1+n*m
source(0), sink(2*n*m+1);
*/

台長: Morris
人氣(872) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][五則運算] 533 - Equation Solver
此分類上一篇:[UVA][dp] 10201 - Adventures in Moving - Part IV

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文