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);
        }
    }
  • 相关阅读:
    Cf的一些总结
    Goodbye 2019
    牛客多校第8场 A题
    19牛客多校第二场 H题
    Hihocoder1673
    记一次根据图片原尺寸设置样式,并进行缩放和拖拽
    鱼骨时间轴案例(转自CSDN,原文链接附于文中)
    jQuery横向上下排列鱼骨图形式信息展示代码时光轴样式(转自CSDN,原文链接附于文中)
    mxGraph实现鱼骨图(因果图)(转自CSDN,链接附于文中)
    erlang win64位包下载链接
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5735586.html
Copyright © 2011-2022 走看看