• HDU 4859 海岸线 最小割


    强烈建议阅读一下最小割模型在信息学竞赛中的应用

    当中2.2.2的Optimal Marks一题和此题建模很相像。

    在原图外围虚拟一圈‘D’,我们要最大化的周长,就能够等价为最大化相邻的'D'和'.' 的总对数,也就是最大化相邻格子不同类型的总对数。

    依照论文中的建图方式。我们能够最小化相邻格子不同类型,

    反过来想,略微改变一下建图,就能够最小化相邻格子同样类型

    建图:

    将地图奇偶建图分成二部。我们如果X集表示 . Y集表示 D (仅仅是为了理解方便)

    1、若相邻则连边,容量1。


    2、若当前点在地图上是 . 可是却被分到了Y集,或者当前点是 D ,却被分到了X集,就和源点连一条INF的边。

    3、若当前点在地图上是 . 而且被分到了X集。或者当前点是 D 。被分到了Y集,就和汇点连一条INF的边。

    分析一下就知道。仅仅有 . --> . 或者 D --> D 。也就是类型同样的,才干从源流向汇。

    源连接的点是“分错了”的点( X集的D或者Y集的. ),汇连接的点是“分对了”的点(X集的.或者Y集的D),所以假设要从源流到汇,则一定是D->D或者.->.。也就是同样类型的。求出最小割就是最小化同样的。

    最后用总对数减去这个就是答案

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<queue>
    #include<vector>
    #include<string>
    #define eps  1e-12
    #define INF   0x7fffffff
    #define maxn 2700
    using namespace std;
    int n,m;
    int en;
    int st,ed;
    int dis[maxn] ;
    int que[9999999];
    struct edge
    {
    	int to,c,next;
    };
    edge e[9999999];
    int head[maxn];
    void add(int a,int b,int c)
    {
    	e[en].to=b;
    	e[en].c=c;
    	e[en].next=head[a];
    	head[a]=en++;
    	e[en].to=a;
    	e[en].c=0;
    	e[en].next=head[b];
    	head[b]=en++;
    }
    int bfs()
    {
        memset(dis,-1,sizeof(dis));
        dis[st]=0;
        int front=0,rear=0;
        que[rear++]=st;
        while(front<rear)
        {
            int j=que[front++];
            for(int k=head[j];k!=-1;k=e[k].next)
            {
                int i=e[k].to;
    			if(dis[i]==-1&&e[k].c)
                {
                    dis[i] = dis[j]+ 1 ;
                    que[rear++]=i;
                    if(i==ed) return true;
                }
            }
        }
        return false;
    }
    int dfs(int x,int mx)
    {
        int i,a;
        if(x==ed) return mx ;
        int ret=0;
        for(int k=head[x];k!=-1&&ret<mx;k=e[k].next)
        {
            if(e[k].c&&dis[e[k].to]==dis[x]+1)
            {
                int dd=dfs(e[k].to,min(e[k].c,mx-ret));
                e[k].c-=dd;
                e[k^1].c+=dd;
                ret+=dd;
            }
        }
        if(!ret) dis[x]=-1;
        return ret;
    }
    void init()
    {
        en=0;
        st=(n+2)*(m+2)+1;
        ed=st+1;
    	memset(head,-1,sizeof(head));
    }
    char mp[55][55];
    int id[55][55];
    int dx[]={0,0,-1,1};
    int dy[]={-1,1,0,0};
    int isok(int x,int y) {return x>=0&&x<=n+1&&y>=0&&y<=m+1;}
    void build()
    {
        int x,y,z;
        memset(mp,0,sizeof(mp));
        for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
    
        for(int i=0,ID=0;i<=n+1;i++)
            for(int j=0;j<=m+1;j++,ID++)
            {
                if(mp[i][j]==0) mp[i][j]='D';
                id[i][j]=ID;
            }
        for(int i=0;i<=n+1;i++)
        {
            for(int j=0;j<=m+1;j++)
            {
                if(mp[i][j]=='D'&&i%2==j%2||mp[i][j]=='.'&&i%2!=j%2) add(st,id[i][j],INF);
                if(mp[i][j]=='D'&&i%2!=j%2||mp[i][j]=='.'&&i%2==j%2) add(id[i][j],ed,INF);
                for(int d=0;d<4;d++)
                {
                    int ii=i+dx[d],jj=j+dy[d];
                    if(isok(ii,jj)) add(id[i][j],id[ii][jj],1);
                }
            }
        }
    }
    int dinic()
    {
        int tmp=0;
        int maxflow=0;
        while(bfs())
        {
            while(tmp=dfs(st,INF)) maxflow+=tmp;
        }
        return maxflow;
    }
    int main()
    {
        int cas,ca=1;
        scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d%d",&n,&m);
            init();
            build();
            printf("Case %d: %d
    ",ca++,(n+2)*(m+1)+(m+2)*(n+1)-dinic());
        }
        return 0;
    }
    


  • 相关阅读:
    各种现代方法和技术在储集层研究中的运用
    “汇报能力”的要求和构建
    个人核心竞争力的构建
    “盐荒”子孙的悲哀
    对数据及数据库的理解
    浅谈大学综合素质培养的重要性
    我看兴趣爱好
    Access数据库连接字符串
    常用css缩略语
    中文与韩、日文混排出现在Gb2312编码的Aspx的处理方法
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6958991.html
Copyright © 2020-2023  润新知