bzoj 1412: [ZJOI2009]狼和羊的故事

news/2024/8/26 16:14:00

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

最小割。源点向羊,狼向汇点连流量为INF的边。羊连空地,空地互连,空地连空地。【含义自己YY下】
然后跑最大流即可
【手残把源点向狼,狼向汇点的流量写成1了】

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int head[100001];
struct map
{
	 int f;
	 int s,t;
     int next;
}a[400001];
int b[5001];
int edge;
int p;
int q[400001],d[400001];
inline void add(int s,int t,int f)
{
     a[edge].next=head[s];
     head[s]=edge;
     a[edge].s=s;
     a[edge].t=t;
     a[edge].f=f;
}
inline bool bfs()
{
     int l=0,r=0;
     memset(q,0,sizeof(q));
     r++;
     q[r]=0;
     memset(d,-1,sizeof(d));
     d[0]=0;
     int i,k;
     while(l<r)
     {
     	  l++;
          int k=q[l];
          for(i=head[k];i!=0;i=a[i].next)
          {
               if(a[i].f>0&&d[a[i].t]==-1)
               {
                    d[a[i].t]=d[k]+1;
                    r++;
                    q[r]=a[i].t;
               }
          }
     }
     if(d[p]>=0)
          return true;
     return false;
}
inline int dfs(int k,int s)
{
     if(k==p)
          return s;
     int t=s;
     int i;
     for(i=head[k];i!=0;i=a[i].next)
     {
          if(d[a[i].t]==d[k]+1&&a[i].f>0)
          {
               int xx=dfs(a[i].t,min(s,a[i].f));
               a[i].f-=xx;
               if(i%2==0)
                    a[i-1].f+=xx;
               else
                    a[i+1].f+=xx;
               s-=xx;
          }
     }
     return t-s;
}
inline int maxflow()
{
     int s=0;
     while(bfs())
          s+=dfs(0,2100000000);
     return s;
}
int map[101][101];
int main()
{
     int n,m;
     scanf("%d%d",&n,&m);
     int i,j;
     p=n*m+1;
     for(i=1;i<=n;i++)
     {
          for(j=1;j<=m;j++)
          {
               scanf("%d",&map[i][j]);
               if(map[i][j]==1)
               {
                    edge++;
                    add(0,(i-1)*m+j,2100000000);
                    edge++;
                    add((i-1)*m+j,0,0);
               }
               else if(map[i][j]==2)
               {
                    edge++;
                    add((i-1)*m+j,p,2100000000);
                    edge++;
                    add(p,(i-1)*m+j,0);
               }
          }
     }
     for(i=1;i<=n;i++)
     {
          for(j=1;j<=m;j++)
          {
               if(map[i][j]==1||map[i][j]==0)
               {
                    if(i-1>0)
                    {
                         if(map[i-1][j]==2||map[i-1][j]==0)
                         {
                              edge++;
                              add((i-1)*m+j,(i-2)*m+j,1);
                              edge++;
                              add((i-2)*m+j,(i-1)*m+j,0);
                         }
                    }
                    if(j-1>0)
                    {
                         if(map[i][j-1]==2||map[i][j-1]==0)
                         {
                              edge++;
                              add((i-1)*m+j,(i-1)*m+j-1,1);
                              edge++;
                              add((i-1)*m+j-1,(i-1)*m+j,0);
                         }
                    }
                    if(i+1<=n)
                    {
                         if(map[i+1][j]==2||map[i+1][j]==0)
                         {
                              edge++;
                              add((i-1)*m+j,i*m+j,1);
                              edge++;
                              add(i*m+j,(i-1)*m+j,0);
                         }
                    }
                    if(j+1<=m)
                    {
                         if(map[i][j+1]==2||map[i][j+1]==0)
                         {
                              edge++;
                              add((i-1)*m+j,(i-1)*m+j+1,1);
                              edge++;
                              add((i-1)*m+j+1,(i-1)*m+j,0);
                         }
                    }
               }
          }
     }
     printf("%d\n",maxflow());
     return 0;
}



http://www.niftyadmin.cn/n/943257.html

相关文章

CF 1178 F1

题意&#xff1a;n个格子&#xff0c;编号1~n&#xff0c;n种颜色的油漆 &#xff0c;编号1~n&#xff0c;每次依次选第i种颜色并将一段区间内全部涂成颜色i&#xff0c;区间内颜色被覆盖&#xff0c;可以涂色的前提是这一区间是相同的颜色&#xff0c;所以你可以认为最初n个格…

17年广东省赛——C,Stokpie(思维)

Call对应函数式&#xff1a;KX-PX-C Put对应函数式&#xff1a;PX-KX-C 分析&#xff1a; 1.建立一个结构体&#xff0c;存储类型type&#xff08;Call或Put&#xff09;&#xff0c;以及C,P,K。 2.输入完后&#xff0c;按P进行从小到大排序。 3.排完序后&#xff0c;每个区间段…

BZOJ 4244 邮戳拉力赛

题意&#xff1a; 思路&#xff1a; 参考博客 https://blog.csdn.net/forever_shi/article/details/84931438 /**************************************************************Problem: 4244User: fufckLanguage: CResult: AcceptedTime:8364 msMemory:72076 kb *********…

bzoj 1066: [SCOI2007]蜥蜴

Description 在一个r行c列的网格地图中有一些高度不同的石柱&#xff0c;一些石柱上站着一些蜥蜴&#xff0c;你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1&#xff0c;蜥蜴的跳跃距离是d&#xff0c;即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石…

组合数的一些模板(好用)

一、 ll qpow(ll a,ll b,ll p) {ll ret1;a%p;while(b){if(b&1) retret*a%p;b/2;aa*a%p;}return ret; } 二、Lucas ll lucas(ll n,ll m,ll p) {if(m0) return 1;return C(n%p,m%p,p)*lucas(n/p,m/p,p)%p; } 三、C(n,m) 方案一&#xff1a;&#xff08;直接算&#xff0…

bzoj 1934: [Shoi2007]Vote 善意的投票

Description 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉。对他们来说&#xff0c;这个问题并不是很重要&#xff0c;于是他们决定发扬谦让精神。虽然每个人都有自己的主见&#xff0c;但是为了照顾一下自己朋友的想法&#xff0c;他们也可以投和自己本来意愿相反的票。我…

bzoj 1706: [usaco2007 Nov]relays 奶牛接力跑

Description FJ的N(2 < N < 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目。至于进行接力跑的地点 自然是在牧场中现有的T(2 < T < 100)条跑道上。 农场上的跑道有一些交汇点&#xff0c;每条跑道都连结了两个不同的交汇点 I1_i和I2_i(1 < I1_i < 1,0…

杭电ACM——1247,Hat’s Words(Trie树)

这道题是有问题的&#xff0c;一个单词是可以被另外一个单词拼接两次得到的&#xff0c;如ab&#xff0c;abab&#xff0c;输出是abab&#xff0c;然而原题确指明&#xff0c;某个单词当且仅当是另外字典里的两个单词拼接的&#xff0c;才是一个hat’s word&#xff0c;实际上这…