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);
        }
    }
  • 相关阅读:
    PID控制算法的C语言实现六 抗积分饱和的PID控制算法C语言实现
    PID控制算法的C语言实现五 积分分离的PID控制算法C语言实现
    python获取两个dict的不同
    将nosetests的echo结果保存到本地文件
    django 配置中STATICFILES_DIRS 和STATIC_ROOT不能同时出现
    Windows下使用最新的JDK1.7.0_51以上版本连接Jenkins出现SecurityException
    jenkins 启动slave,出现com.sun.deploy.net.FailedDownloadException: Unable to load resource: http://127.0.0.1:8080/jnlpJars/remoting.jar
    windows 下查看端口占用情况
    phpstorm + x-debug 进行php调试
    jenkins 升级jdk到1.8.0 报java.io.IOException:Unable to read /var/lib/jenkins/config.xml
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5735586.html
Copyright © 2011-2022 走看看