HUNAN OJ 11567 Escaping

来源:互联网 发布:淘宝涉水批文 编辑:程序博客网 时间:2024/05/29 19:05

Problem description
One day, Large cruise ”Wu Kong” at sea. The station is represented by a square n*n divided into 1*1 blocks. Unfortunately , ” Wu Kong” hit an iceberg .It will sink after t minutes ,then every people die. However, there will be some life-saving equipment in some rooms(not only one), People from one room to reach another adjacent room (only four) needs one minute .If the people on board to get these life-saving devices so that they will survive, find the greatest number of people can survive.

Input
The first line contains two integers n and t (2 ≤ n ≤ 10, 1 ≤ t ≤ 10). Each of the next n lines contains n integers(0<=A[i][j]<=9).the people number at this time. Each of the next n more lines contains n integers, Indicates that the room have the number of life-saving equipment(0<=B[i][j]<=9).

Output
Print a single number — the maximum number of people who will be saved.

Sample Input
3 3
1 0 0
1 0 0
1 0 0
0 0 0
0 0 0
0 0 3

Sample Output
2

BFS预处理,然后建图跑最大流

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <algorithm>#include <queue>#include <set>#include <bitset>#include <climits>using namespace std;const int INF = 0x3f3f3f3f;const int MAXN = 200000;const int MAXM = 400005;int n, m, u, v, w;struct point{    int x, y, step;    friend bool operator < (const point& a, const point& b)    {        return a.step > b.step;    }};int mp[15][15], a, t, x[15][15];int dirx[] = {1, -1, 0, 0};int diry[] = {0, 0, 1, -1};bool vis[15][15];struct Edge{    int to, next, flow;} edge[MAXM];int head[MAXN], tot;void add(int u, int v, int w){    edge[tot].to = v;    edge[tot].flow = w;    edge[tot].next = head[u];    head[u] = tot++;    edge[tot].to = u;    edge[tot].flow = 0;    edge[tot].next = head[v];    head[v] = tot++;}int dep[MAXN];bool bfs(int s, int t){    int u;    memset(dep, -1, sizeof(dep));    queue <int> q;    q.push(s);    dep[s] = 0;    while(!q.empty())    {        u = q.front();        q.pop();        for(int i = head[u]; ~i; i = edge[i].next)        {            int v = edge[i].to;            if(dep[v] == -1 && edge[i].flow > 0)            {                dep[v] = dep[u] + 1;                if(v == t)return true;                q.push(v);            }        }    }    return false;}int dfs(int s, int t, int x){    if(s == t)return x;    int ans = x;    for(int i = head[s]; ~i; i = edge[i].next)    {        int v = edge[i].to;        if(dep[v] == dep[s] + 1 && edge[i].flow > 0)        {            int minn = dfs(v, t, min(x, edge[i].flow));            edge[i].flow -= minn;            edge[i ^ 1].flow += minn;            x -= minn;        }    }    return ans - x;}int dinic(){    int ans = 0;    while(bfs(1, n))ans += dfs(1, n, INF);    return ans;}bool judge(int x, int y){    return (x >= 0 && x < a && y >= 0 && y < a && !vis[x][y]);}void pre(point x){    priority_queue <point> q;    point F, N;    q.push(x);    int node = x.x * a + x.y + 2;    memset(vis, false, sizeof(vis));    while(!q.empty())    {        F = q.top();        q.pop();        if(F.step > t)break;        //cout<<mp[2][2]<<endl;        if(mp[F.x][F.y] >= 1)add(node, F.x * a + F.y + a * a + 2, INF);        for(int i = 0; i < 4; ++i)        {            N.x = F.x + dirx[i];            N.y = F.y + diry[i];            if(judge(N.x, N.y))            {                vis[N.x][N.y] = true;                N.step = F.step + 1;                q.push(N);            }        }    }}point Q;int main(){    //freopen("in.txt", "r", stdin);    while(scanf("%d%d", &a, &t) == 2)    {        tot = 0;        memset(head, -1, sizeof(head));        for(int i = 0; i < a; ++i)        {            for(int j = 0; j < a; ++j)scanf("%d", &x[i][j]);        }        n = 2 * a * a + 2;        for(int i = 0; i < a; ++i)        {            for(int j = 0; j < a; ++j)            {                scanf("%d", &mp[i][j]);                if(mp[i][j] >= 1)add(a * a + 2 + i * a + j, n, mp[i][j]);            }        }        for(int i = 0; i < a; ++i)        {            for(int j = 0; j < a; ++j)            {                if(x[i][j] >= 1)                {                    add(1, i * a + j + 2, x[i][j]);                    Q.step = 0;                    Q.x = i;                    Q.y = j;                    pre(Q);                }            }        }        printf("%d\n", dinic());    }    return 0;}
0 0
原创粉丝点击