• [bzoj1412]狼和羊的故事


    题意是需要在某些相邻的节点中建立栅栏使得这两个点不能直接走到,使得所有狼的领地和羊的领地两两不能(间接)走到最少需要多少栅栏。

    很显然,将S向所有羊连边,狼向T连边(流量为inf),然后任意相邻两个点连边(羊/狼之间可以不连),求最小割即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 10005
     4 #define id (i-1)*m+j
     5 #define inf 0x3f3f3f3f
     6 struct ji{
     7     int nex,to,len;
     8 }edge[N*10];
     9 queue<int>q;
    10 int E,n,m,p,head[N],work[N],d[N];
    11 void add(int x,int y,int z){
    12     edge[E].nex=head[x];
    13     edge[E].to=y;
    14     edge[E].len=z;
    15     head[x]=E++;
    16     if (E&1)add(y,x,0);
    17 }
    18 bool bfs(){
    19     memset(d,-1,sizeof(d));
    20     q.push(0);
    21     d[0]=0;
    22     while (!q.empty()){
    23         int k=q.front();
    24         q.pop();
    25         for(int i=head[k];i!=-1;i=edge[i].nex)
    26             if ((edge[i].len)&&(d[edge[i].to]<0)){
    27                 d[edge[i].to]=d[k]+1;
    28                 q.push(edge[i].to);
    29             }
    30     }
    31     return d[n*m+1]>=0;
    32 }
    33 int dfs(int k,int s){
    34     if (k>n*m)return s;
    35     for(int &i=work[k];i!=-1;i=edge[i].nex)
    36         if ((edge[i].len)&&(d[edge[i].to]==d[k]+1)){
    37             int p=dfs(edge[i].to,min(s,edge[i].len));
    38             if (p){
    39                 edge[i].len-=p;
    40                 edge[i^1].len+=p;
    41                 return p;
    42             }
    43         }
    44     return 0;
    45 }
    46 int dinic(){
    47     int k,ans=0;
    48     while (bfs()){
    49         memcpy(work,head,sizeof(head));
    50         while (k=dfs(0,inf))ans+=k;
    51     }
    52     return ans;
    53 }
    54 int main(){
    55     scanf("%d%d",&n,&m);
    56     memset(head,-1,sizeof(head));
    57     for(int i=1;i<=n;i++)
    58         for(int j=1;j<=m;j++){
    59             scanf("%d",&p);
    60             if (p==1)add(0,id,inf);
    61             if (p==2)add(id,n*m+1,inf);
    62             if (j>1)add(id,id-1,1);
    63             if (j<m)add(id,id+1,1);
    64             if (i>1)add(id,id-m,1);
    65             if (i<n)add(id,id+m,1);
    66         }
    67     printf("%d",dinic());
    68 }
    View Code
  • 相关阅读:
    System.Text.Json 自定义Converter实现时间转换
    WeihanLi.Npoi 根据模板导出Excel
    用 F# 手写 TypeScript 转 C# 类型绑定生成器
    【C#】写文件时如何去掉编码前缀
    一个支持 CodeFirst/DbFirst/ModelFirst 的数据库小工具
    C#设计模式学习笔记:(15)迭代器模式
    【WPF学习】第四十六章 效果
    C# 如何实现完整的INI文件读写类
    Blend 修改TreeViewItem样式
    C#设计模式学习笔记:(16)观察者模式
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249096.html
Copyright © 2020-2023  润新知