• bzoj1412 [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
     
    正解:最小割。
    最小割模板题,我也不知道为什么要写这题。。
     
     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define inf (1<<30)
     6 #define N (10005)
     7 
     8 using namespace std;
     9 
    10 struct edge{ int nt,to,flow,cap; }g[200005];
    11 
    12 int head[N],d[N],q[N],a[105][105],id[105][105],S,T,n,m,num,cnt;
    13 
    14 il int gi(){
    15   RG int x=0,q=1; RG char ch=getchar();
    16   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    17   if (ch=='-') q=-1,ch=getchar();
    18   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    19   return q*x;
    20 }
    21 
    22 il void insert(RG int from,RG int to,RG int cap){
    23   g[++num]=(edge){head[from],to,0,cap},head[from]=num;
    24   g[++num]=(edge){head[to],from,0,0},head[to]=num; return;
    25 }
    26 
    27 il int bfs(RG int S,RG int T){
    28   memset(d,0,sizeof(d));
    29   RG int h=0,t=1; q[t]=S,d[S]=1;
    30   while (h<t){
    31     RG int x=q[++h],v;
    32     for (RG int i=head[x];i;i=g[i].nt){
    33       v=g[i].to;
    34       if (!d[v] && g[i].cap>g[i].flow){
    35     d[v]=d[x]+1,q[++t]=v;
    36     if (v==T) return 1;
    37       }
    38     }
    39   }
    40   return d[T];
    41 }
    42 
    43 il int dfs(RG int x,RG int T,RG int a){
    44   if (!a || x==T) return a; RG int f,flow=0;
    45   for (RG int i=head[x],v;i;i=g[i].nt){
    46     v=g[i].to;
    47     if (d[v]==d[x]+1 && g[i].cap>g[i].flow){
    48       f=dfs(v,T,min(a,g[i].cap-g[i].flow));
    49       if (!f){ d[v]=-1; continue; }
    50       g[i].flow+=f,g[i^1].flow-=f;
    51       flow+=f,a-=f; if (!a) return flow;
    52     }
    53   }
    54   return flow;
    55 }
    56 
    57 il int maxflow(RG int S,RG int T){
    58   RG int flow=0;
    59   while (bfs(S,T)) flow+=dfs(S,T,inf); return flow;
    60 }
    61 
    62 int main(){
    63 #ifndef ONLINE_JUDGE
    64   freopen("story.in","r",stdin);
    65   freopen("story.out","w",stdout);
    66 #endif
    67   n=gi(),m=gi(),num=1,S=++cnt,T=++cnt;
    68   for (RG int i=1;i<=n;++i)
    69     for (RG int j=1;j<=m;++j) a[i][j]=gi(),id[i][j]=++cnt;
    70   for (RG int i=1;i<=n;++i)
    71     for (RG int j=1;j<=m;++j){
    72       if (a[i][j]==2) insert(id[i][j],T,inf); else{
    73     if (a[i][j]) insert(S,id[i][j],inf);
    74     if (i && a[i-1][j]!=1) insert(id[i][j],id[i-1][j],1);
    75     if (j && a[i][j-1]!=1) insert(id[i][j],id[i][j-1],1);
    76     if (i<n && a[i+1][j]!=1) insert(id[i][j],id[i+1][j],1);
    77     if (j<m && a[i][j+1]!=1) insert(id[i][j],id[i][j+1],1);
    78       }
    79     }
    80   cout<<maxflow(S,T); return 0;
    81 }
  • 相关阅读:
    一个小案例精通lamda表达式
    你想被开除吗?来看看程序员【离职小技巧】吧
    让 Flutter 在鸿蒙系统上跑起来
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    环形单链表的增删改查、约瑟夫环两种解法
    一万字详解 Redis Cluster Gossip 协议
    Lambda表达式
    Linux系统中如何进入退出vim编辑器,方法及区别
    成为博客主的第一天
    【秋招内推】近期互联网公司秋招内推合集
  • 原文地址:https://www.cnblogs.com/wfj2048/p/8213783.html
Copyright © 2020-2023  润新知