zoukankan      html  css  js  c++  java
  • ZJOI2009 狼和羊的故事

    题目链接:戳我

    就是将一个图分成两块,不联通。
    显然是最小割。

    考虑怎么建图。
    我们将S和羊连起来,T和狼连起来。
    那么就是遍历一遍每个格子,然后判断它的四周。如果领地一样需要continue。如果不一样,就是羊向空地、狼领地连边,空地向空地、狼连边,狼不连边。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define S 0
    #define T n*m+1
    #define MAXN 100010
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,m,t=1;
    int head[MAXN],cur[MAXN],dis[MAXN],a[110][110],done[110][110];
    int move_x[5]={0,0,1,-1},move_y[5]={1,-1,0,0};
    struct Edge{int nxt,to,dis;}edge[MAXN<<1];
    inline void add(int from,int to,int dis)
    {
        edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;
        edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=0,head[to]=t;
    }
    inline bool bfs()
    {
        memset(dis,0x3f,sizeof(dis));
        memcpy(cur,head,sizeof(head));
        queue<int>q;
        q.push(S);
        dis[S]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(dis[v]==0x3f3f3f3f&&edge[i].dis)
                {
                    dis[v]=dis[u]+1;
                    q.push(v);
                }
            }
        }
        if(dis[T]==0x3f3f3f3f) return false;
        return true;
    }
    inline int dfs(int x,int f)
    {
        if(x==T||!f) return f;
        int used=0,w;
        for(int i=cur[x];i;i=edge[i].nxt)
        {
            cur[x]=i;
            if(dis[edge[i].to]==dis[x]+1&&(w=dfs(edge[i].to,min(f,edge[i].dis))))
            {
                used+=w,f-=w;
                edge[i].dis-=w,edge[i^1].dis+=w;
                if(!f) break;
            }
        }
        return used;
    }
    inline int dinic()
    {
        int cur_ans=0;
        while(bfs()) cur_ans+=dfs(S,INF);
        return cur_ans;
    }
    inline int id(int x,int y){return m*(x-1)+y;}
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&a[i][j]);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(a[i][j]==2) add(S,id(i,j),INF);
                else if(a[i][j]==1) add(id(i,j),T,INF);
                for(int k=0;k<4;k++)
                {
                    int xx=move_x[k]+i;
                    int yy=move_y[k]+j;
                    if(xx<1||xx>n||yy<1||yy>m) continue;
                    bool flag=false;
                    if(a[i][j]==0&&(a[xx][yy]==0||a[xx][yy]==1)) flag=true;
                    if(a[i][j]==1&&(a[xx][yy]==0||a[xx][yy]==1)) flag=true;
                    if(a[i][j]==2&&(a[xx][yy]==0||a[xx][yy]==1)) flag=true;
                    if(flag==true) add(id(i,j),id(xx,yy),1);
                }
            }
        }
        printf("%d
    ",dinic());
        return 0;
    }
    
  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10805356.html
Copyright © 2011-2022 走看看