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;
    }
    
  • 相关阅读:
    第十四周 Leetcode 315. Count of Smaller Numbers After Self(HARD) 主席树
    POJ1050 To the Max 最大子矩阵
    POJ1259 The Picnic 最大空凸包问题 DP
    POJ 3734 Blocks 矩阵递推
    POJ2686 Traveling by Stagecoach 状态压缩DP
    iOS上架ipa上传问题那些事
    深入浅出iOS事件机制
    iOS如何跳到系统设置里的各种设置界面
    坑爹的私有API
    业务层网络请求封装
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10805356.html
Copyright © 2011-2022 走看看