zoukankan      html  css  js  c++  java
  • 1412. [ZJOI2009]狼和羊的故事【最小割】

    Description

    “狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

    Input

    文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

    Output

    文件中仅包含一个整数ans,代表篱笆的最短长度。

    Sample Input

    2 2
    2 2
    1 1

    Sample Output

    2

    数据范围
    10%的数据 n,m≤3
    30%的数据 n,m≤20
    100%的数据 n,m≤100

    最小割……好久不做网络流这么简单的建模都不会了……
    把狼和周围的空地和羊连边,空地和周围的空地和羊连边
    S连狼,INF  E连羊,INF

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<queue>
     6 #define MAXM (1000000+10)
     7 #define MAXN (30000+10)
     8 #define id(x,y) (x-1)*m+y
     9 using namespace std;
    10 struct node
    11 {
    12     int Flow;
    13     int next;
    14     int to;
    15 } edge[MAXM*2];
    16 int Depth[MAXN];
    17 int head[MAXN],num_edge;
    18 int n,m,s,e,x,y,INF,a[105][105];
    19 int dx[5]= {0,1,-1,0,0},dy[5]= {0,0,0,1,-1};
    20 queue<int>q;
    21 
    22 void add(int u,int v,int l)
    23 {
    24     edge[++num_edge].to=v;
    25     edge[num_edge].Flow=l;
    26     edge[num_edge].next=head[u];
    27     head[u]=num_edge;
    28 }
    29 
    30 bool Bfs(int s,int e)
    31 {
    32     memset(Depth,0,sizeof(Depth));
    33     q.push(s);
    34     Depth[s]=1;
    35     while (!q.empty())
    36     {
    37         int x=q.front();
    38         q.pop();
    39         for (int i=head[x]; i!=0; i=edge[i].next)
    40             if (!Depth[edge[i].to] && edge[i].Flow>0)
    41             {
    42                 Depth[edge[i].to]=Depth[x]+1;
    43                 q.push(edge[i].to);
    44             }
    45     }
    46     return Depth[e];
    47 }
    48 
    49 int Dfs(int x,int low)
    50 {
    51     int Min,f=0;
    52     if (x==e || low==0)
    53         return low;
    54     for (int i=head[x]; i!=0; i=edge[i].next)
    55         if (edge[i].Flow>0 && Depth[edge[i].to]==Depth[x]+1 && (Min=Dfs(edge[i].to,min(low,edge[i].Flow))))
    56         {
    57             edge[i].Flow-=Min;
    58             edge[((i-1)^1)+1].Flow+=Min;
    59             low-=Min;
    60             f+=Min;
    61             if (low==0) return f;
    62         }
    63     if (!f) Depth[x]=-1;
    64     return f;
    65 }
    66 
    67 int Dinic(int s,int e)
    68 {
    69     int Ans=0;
    70     while (Bfs(s,e))
    71         Ans+=Dfs(s,0x7fffffff);
    72     return Ans;
    73 }
    74 
    75 int main()
    76 {
    77     memset(&INF,0x7f,sizeof(INF));
    78     s=0,e=10001;
    79     scanf("%d%d",&n,&m);
    80     for (int i=1; i<=n; ++i)
    81         for (int j=1; j<=m; ++j)
    82         {
    83             scanf("%d",&a[i][j]);
    84             if (a[i][j]==2) add(s,id(i,j),INF),add(id(i,j),s,0);
    85             if (a[i][j]==1) add(id(i,j),e,INF),add(e,id(i,j),0);
    86             for (int k=1; k<=4; ++k)
    87             {
    88                 int x=i+dx[k],y=j+dy[k];
    89                 if (x<1 || x>n || y<1 || y>m) continue;
    90                 if (a[i][j]==2 && a[x][y]!=2 || a[i][j]==0 && a[i][j]!=2)
    91                     add(id(i,j),id(x,y),1),add(id(x,y),id(i,j),0);
    92             }
    93         }
    94     printf("%d
    ",Dinic(s,e));
    95 }
  • 相关阅读:
    vue学习目录
    充分利用 SQL Server Reporting Services 图表
    MSCRM 用户登录日志
    Microsoft Dynamics CRM MVP
    在SSRS 里实现 SUMIF
    MSCRM 报表显示 rsprocessingaborted 错误
    电商CRM的痛点在哪里?
    MSCRM 2011/2013/2015 修改显示记录数
    MSCRM 2013/2015 Ribbon Editor
    Q:解决每天第一次打开MSCRM系统展示慢的问题
  • 原文地址:https://www.cnblogs.com/refun/p/8682279.html
Copyright © 2011-2022 走看看