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);
        }
    }
  • 相关阅读:
    java 测试 (junit+ junit 断言 + postman)
    junit 运行(eclipse + IDEA)
    junit 常用注解 + junit 断言详解
    工作周报模板
    spring boot tomcat 部署
    spring boot 集成JSP
    spring boot 集成 Mybatis,JPA
    JPA 常用注解
    员工年终绩效考核表模板
    2013 Noip提高组 Day1
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5735586.html
Copyright © 2011-2022 走看看