zoukankan      html  css  js  c++  java
  • hdu 3046(最小割)

    Pleasant sheep and big big wolf

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2794    Accepted Submission(s): 1150


    Problem Description
    In ZJNU, there is a well-known prairie. And it attracts pleasant sheep and his companions to have a holiday. Big big wolf and his families know about this, and quietly hid in the big lawn. As ZJNU ACM/ICPC team, we have an obligation to protect pleasant sheep and his companions to free from being disturbed by big big wolf. We decided to build a number of unit fence whose length is 1. Any wolf and sheep can not cross the fence. Of course, one grid can only contain an animal.
    Now, we ask to place the minimum fences to let pleasant sheep and his Companions to free from being disturbed by big big wolf and his companions.
     
    Input
    There are many cases.
    For every case:

    N and M(N,M<=200)
    then N*M matrix:
    0 is empty, and 1 is pleasant sheep and his companions, 2 is big big wolf and his companions.
     
    Output
    For every case:

    First line output “Case p:”, p is the p-th case;
    The second line is the answer.
     
    Sample Input
    4 6 1 0 0 1 0 0 0 1 1 0 0 0 2 0 0 0 0 0 0 2 0 1 1 0
     
    Sample Output
    Case 1: 4
     
    Source
    题意:给出一个n*m的矩阵,里面有一些狼(2)和一些羊(1),现在要将狼羊隔开,可以在两点之间建造围栏将狼隔在外面,问围栏的最小长度应该是多少?
    题解:构图,将每个点与其边上的点连接起来,容量为1,这样的话割这条边就等于是建造了一个长度为1的围栏,然后建造一个超级源点和羊连起来,容量为INF,因为我们不能去割羊,狼与超级汇点同理.跑一遍最大流即为答案。
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    using namespace std;
    const int INF = 999999999;
    const int N = 45005;
    const int M = 1000005;
    struct Edge{
        int v,w,next;
    }edge[M];
    int head[N];
    int level[N];
    int tot;
    void init()
    {
        memset(head,-1,sizeof(head));
        tot=0;
    }
    void addEdge(int u,int v,int w,int &k)
    {
        edge[k].v = v,edge[k].w=w,edge[k].next=head[u],head[u]=k++;
        edge[k].v = u,edge[k].w=0,edge[k].next=head[v],head[v]=k++;
    }
    int BFS(int src,int des)
    {
        queue<int>q;
        memset(level,0,sizeof(level));
        level[src]=1;
        q.push(src);
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            if(u==des) return 1;
            for(int k = head[u]; k!=-1; k=edge[k].next)
            {
                int v = edge[k].v;
                int w = edge[k].w;
                if(level[v]==0&&w!=0)
                {
                    level[v]=level[u]+1;
                    q.push(v);
                }
            }
        }
        return -1;
    }
    int dfs(int u,int des,int increaseRoad){
        if(u==des||increaseRoad==0) {
            return increaseRoad;
        }
        int ret=0;
        for(int k=head[u];k!=-1;k=edge[k].next){
            int v = edge[k].v,w=edge[k].w;
            if(level[v]==level[u]+1&&w!=0){
                int MIN = min(increaseRoad-ret,w);
                w = dfs(v,des,MIN);
                if(w > 0)
                {
                    edge[k].w -=w;
                    edge[k^1].w+=w;
                    ret+=w;
                    if(ret==increaseRoad){
                        return ret;
                    }
                }
                else level[v] = -1;
                if(increaseRoad==0) break;
            }
        }
        if(ret==0) level[u]=-1;
        return ret;
    }
    int Dinic(int src,int des)
    {
        int ans = 0;
        while(BFS(src,des)!=-1) ans+=dfs(src,des,INF);
        return ans;
    }
    int n,m;
    int graph[250][250];
    int P(int x,int y){
        return (x-1)*m+y;
    }
    int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    int main(){
        int t=  1;
        while(scanf("%d%d",&n,&m)!=EOF){
            init();
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%d",&graph[i][j]);
                }
            }
            int src = 0,des = n*m+1;
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    if(graph[i][j]==1){
                        addEdge(src,P(i,j),INF,tot);
                    }
                    if(graph[i][j]==2){
                        addEdge(P(i,j),des,INF,tot);
                    }
                    for(int k=0;k<4;k++){
                        int x = i+dir[k][0],y = j+dir[k][1];
                        if(x>n||x<1||y>m||y<1) continue;
                        addEdge(P(i,j),P(x,y),1,tot);
                    }
                }
            }
            int mincut = Dinic(src,des);
            printf("Case %d:
    ",t++);
            printf("%d
    ",mincut);
        }
    }
  • 相关阅读:
    Eclipse svn插件包
    最新版STS因为JDK版本太低无法启动的解决办法
    maven 项目无法发布,无法编译的解决办法
    maven依赖本地非repository中的jar包
    微信公众平台开发(2)-消息封装
    微信公众平台开发(4)-自定义菜单
    限制必须使用微信打开网页
    移动设备页面自适应
    微信公众平台开发(5)-上传下载多媒体文件
    微信公众平台开发(3)-回复消息
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5735586.html
Copyright © 2011-2022 走看看