zoukankan      html  css  js  c++  java
  • bzoj1412: [ZJOI2009]狼和羊的故事(最小割)

    1412: [ZJOI2009]狼和羊的故事

    题目:传送门

    题解:

       一道最小割的基础水题。。。

       基本建模啊:

       st连羊,狼连ed,空地和羊狼连边,羊和空地和狼连边

       跑一遍dicnic就出答案了

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int dx[5]={0,-1,1,0,0};
     8 const int dy[5]={0,0,0,-1,1};
     9 struct node
    10 {
    11     int x,y,c,next,other;
    12 }a[210000];int len,last[110000];
    13 int n,m,st,ed,head,tail;
    14 int map[110][110];
    15 void ins(int x,int y,int c)
    16 {
    17     int k1,k2;
    18     k1=++len;
    19     a[len].x=x;a[len].y=y;a[len].c=c;
    20     a[len].next=last[x];last[x]=len;
    21      
    22     k2=++len;
    23     a[len].x=y;a[len].y=x;a[len].c=0;
    24     a[len].next=last[y];last[y]=len;
    25      
    26     a[k1].other=k2;
    27     a[k2].other=k1;
    28 }
    29 int h[110000],list[110000];
    30 bool bfs()
    31 {
    32     memset(h,0,sizeof(h));h[st]=1;
    33     head=1;tail=2;list[1]=st;
    34     while(head!=tail)
    35     {
    36         int x=list[head];
    37         for(int k=last[x];k;k=a[k].next)
    38         {
    39             int y=a[k].y;
    40             if(h[y]==0 && a[k].c)
    41             {
    42                 h[y]=h[x]+1;
    43                 list[tail++]=y;
    44             }
    45         }
    46         head++;
    47     }
    48     if(h[ed])return true;
    49     return false;
    50 }
    51 int find_flow(int x,int flow)
    52 {
    53     if(x==ed)return flow;
    54     int s=0,t;
    55     for(int k=last[x];k;k=a[k].next)
    56     {
    57         int y=a[k].y;
    58         if(h[y]==h[x]+1 && a[k].c>0 && flow>s)
    59         {
    60             s+=t=find_flow(y,min(a[k].c,flow-s));
    61             a[k].c-=t;a[a[k].other].c+=t;
    62         }
    63     }
    64     if(s==0)h[x]=0;
    65     return s;
    66 }
    67 int d[110][110];
    68 int main()
    69 {
    70     scanf("%d%d",&n,&m);
    71     len=0;memset(last,0,sizeof(last));
    72     st=n*m+1;ed=st+1;int ss=0;
    73     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)d[i][j]=++ss;
    74     memset(map,-1,sizeof(map));
    75     for(int i=1;i<=n;i++)
    76         for(int j=1;j<=m;j++)
    77         {
    78             scanf("%d",&map[i][j]);
    79             if(map[i][j]==1)ins(st,d[i][j],999999999);
    80             else if(map[i][j]==2)ins(d[i][j],ed,999999999);
    81         }
    82     for(int i=1;i<=n;i++)
    83         for(int j=1;j<=m;j++)
    84         {
    85             if(map[i][j]==1 || map[i][j]==0)
    86                 for(int k=1;k<=4;k++)
    87                 {
    88                     int ti=i+dx[k],tj=j+dy[k]; 
    89                     if(map[ti][tj]==2 || map[ti][tj]==0)
    90                         ins(d[i][j],d[ti][tj],1);
    91                 } 
    92         }
    93     int ans=0;
    94     while(bfs())ans+=find_flow(st,999999999);
    95     printf("%d
    ",ans);
    96     return 0;
    97
  • 相关阅读:
    单链表反转的2种常见方法
    LeetCode解题报告:Reorder List
    LeetCode解题报告:Binary Tree Postorder Traversal
    LeetCode解题报告:LRU Cache
    LeetCode解题报告:Insertion Sort List
    Java编程杂记
    如何对一个不断更新的HashMap进行排序
    Python快速入门
    Html与CSS快速入门01-基础概念
    JVM快速入门
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8425269.html
Copyright © 2011-2022 走看看