hnu 13182 Drop Zone(网络流 最小割)

Drop Zone
Time Limit: 3000ms, Special Time Limit:7500ms, Memory Limit:65536KB
Total submit users: 4, Accepted users: 2
Problem 13182 : No special judgement
Problem description

Evacuation missions and supply gathering missions are conducted on a regular basis by special teams. One of the first objectives of these missions is to set up a perimeter with barricades. Barricades are costly and take time to set up, so it is important to reduce the number of barricades necessary to block off an area.

You will be provided with several maps of high-interest drop zones. It is your job to write a program that will output the minimum number of barricades required for each drop zone.

Zombies will begin their approach from outside the map, thus any open area on the border is accessible to zombies. Barricades can be placed between any two adjacent open areas (including the drop zone) to block zombie movement. All zones outside of the map should be considered open areas.

Here is an example of one of the maps you will be provided:



Input

The first number, N (1 <= N <= 20), will be the number of maps. For each map, there will be two parameters, R and C (1 <= R, C <= 150), denoting the number of rows and columns in the map, followed by the map itself as described above. Each row will be on its own line and all rows will have the same number of characters equal to C.


Output

For each map, print a single line containing the minimum number of barricades required to block off the drop zone.


Sample Input
2
7 8
XXX..XXX
XXX..XXX
.....XXX
XXX..XXX
XDDDD.XX
XDDDD...
XXXXXXXX
5 5
XX.XX
.DDD.
XD.DX
X....
X....
Sample Output
3
6

设置栅栏  使得不能外面区域进入到D区域内  要使得栅栏的数量最少  栅栏放置的位置有要求 


思路  构造一个超级源点 一个超级汇点

超级源点与‘.’所在位置建边  权值为0或1或2  分别表示从区域外部连通的数量

两个‘.’之间建边 权值为1  表示这互相之间可以走动

超级汇点与‘D’所在位置建边  权值为1 

如果‘D’与外部区域相连 则要在超级源点与超级汇点之间建边 权值为相连的通道数


#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

#define eps 1e-8
#define op operator
#define MOD  10009
#define MAXN  40010
#define INF 0x7fffffff
#define MEM(a,x)    memset(a,x,sizeof a)
#define ll __int64

using namespace std;

struct Dinic
{
    struct Edge
    {
        int from,to,cap,flow;
        Edge(){}
        Edge(int from,int to,int cap,int flow):from(from),to(to),cap(cap),flow(flow){}
    };
    vector<Edge> edges;
    vector<int> G[MAXN];
    bool vis[MAXN];
    int d[MAXN];
    int cur[MAXN];
    int n,m,s,t,maxflow;

    void init(int n)
    {
        this->n=n;
        for(int i=0;i<=n;i++)
            G[i].clear();
        edges.clear();
    }

    void addedge(int from,int to,int cap)
    {
        edges.push_back(Edge(from,to,cap,0));
        edges.push_back(Edge(to,from,0,0));
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool bfs()
    {
        MEM(vis,0);
        MEM(d,-1);
        queue<int> q;
        q.push(s);
        d[s]=maxflow=0;
        vis[s]=1;
        while(!q.empty())
        {
            int u=q.front(); q.pop();
            int sz=G[u].size();
            for(int i=0;i<sz;i++)
            {
                Edge e=edges[G[u][i]];
                if(!vis[e.to]&&e.cap>e.flow)
                {
                    d[e.to]=d[u]+1;
                    vis[e.to]=1;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int dfs(int u,int a)
    {
        if(u==t||a==0)  return a;
        int sz=G[u].size();
        int flow=0,f;
        for(int &i=cur[u];i<sz;i++)
        {
            Edge &e=edges[G[u][i]];
            if(d[u]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[u][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)  break;
            }
        }
        return flow;
    }

    int Maxflow(int s,int t)
    {
        this->s=s; this->t=t;
        int flow=0;
        while(bfs())
        {
            MEM(cur,0);
            flow+=dfs(s,INF);
        }
        return flow;
    }
}Dic;


int r,c;
char map[200][200];
//int dx[2]={-1,0},dy[2]={0,-1};
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};

int num(int x,int y)
{
    return x*c+y;
}

int main()
{
    int tc;
    scanf("%d",&tc);
    while(tc--)
    {
        scanf("%d%d",&r,&c);
        for(int i=0;i<r;i++)
            scanf("%s",map[i]);
        int st=40000,ed=40001;
        Dic.init(ed);
        int x,y;
        for(int i=0;i<r;i++)
        {
            for(int j=0;j<c;j++)
            {
                if(map[i][j]=='.')
                {
                    Dic.addedge(st,num(i,j),(i==0)+(j==0)+(i==r-1)+(j==c-1));
//                    for(int k=0;k<2;k++)
//                    {
//                        x=i+dx[k]; y=j+dy[k];
//                        if(x>=0&&x<r&&y>=0&&y<c&&map[x][y]=='.')
//                        {
//                            Dic.addedge(num(i,j),num(x,y),1);
//                            Dic.addedge(num(x,y),num(i,j),1);
//                        }
//                        if(x>=0&&x<r&&y>=0&&y<c&&map[x][y]=='D')
//                        {
//                            Dic.addedge(num(i,j),ed,1);
//                        }
//                    }
//                    for(int k=0;k<2;k++)
//                    {
//                        x=i-dx[k]; y=j-dy[k];
//                        if(x>=0&&x<r&&y>=0&&y<c&&map[x][y]=='D')
//                        {
//                            Dic.addedge(num(i,j),ed,1);
//                        }
//                    }
                    for(int k=0;k<4;k++)
                    {
                        x=i+dir[k][0];
                        y=j+dir[k][1];
                        if(x>=0&&x<r&&y>=0&&y<c&&map[x][y]=='.')
                        {
                            Dic.addedge(num(i,j),num(x,y),1);
                        }
                        if(x>=0&&x<r&&y>=0&&y<c&&map[x][y]=='D')
                        {
                            Dic.addedge(num(i,j),ed,1);
                        }
                    }
                }
                if(map[i][j]=='D')
                {
                    Dic.addedge(st,ed,(i==0)+(j==0)+(i==r-1)+(j==c-1));//从外部区域直接进入D区域的数量
                }
            }
        }
        printf("%d\n",Dic.Maxflow(st,ed));
    }
    return 0;
}








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值