• 狼和羊的故事


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

    输入数据
    输入数据存放在文本文件ws.in中。
    文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

    输出数据
    输出数据存放在文本文件ws.out中。
    文件中仅包含一个整数ans,代表篱笆的最短长度。

    样例输入
    2 2
    2 2 
    1 1 

    样例输出
    2

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

    应该是最小割 吧 ,我是参照黄学长的做法 ,qwq ,可以去黄学长那里看一下题解吧。

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <queue>
      6 #include <vector>
      7 const int inf = 1<<30 , maxn = 10000 + 11 , N = 100 ;
      8 using namespace std ;
      9 int n , m , ans , head[maxn] , s , t , cnt , cur[maxn] , jv[N][N] , tot , dis[maxn];
     10 int sj[4][2] = { 0 , 1 , 0 , -1 , 1 , 0 , -1 , 0  } , sg[4] ;
     11 struct id
     12 {
     13     int nxt , to , val ;
     14 } ;
     15 vector < id > edge ;
     16 queue <int> Q ;
     17 
     18 inline void Init(  )
     19 {
     20     freopen( "ws.in" , "r" , stdin ) ;
     21     freopen( "ws.out" , "w" , stdout ) ;
     22 }
     23 
     24 
     25 int read( )
     26 {
     27     char ch = getchar( ) ; int k = 1 , ret = 0 ;
     28     while( ch < '0' || ch > '9' ) { if( ch == '-' ) k = -1 ; ch = getchar( ) ; }
     29      while( ch >= '0' && ch <= '9' ) ret = ret * 10 + ch - '0' , ch = getchar( ) ;
     30     return ret * k ;
     31 }
     32  
     33  
     34 void add( int u , int v , int vi )
     35 {
     36     id a ;
     37     a.nxt = head[u] , a.to = v ;
     38     a.val = vi ; edge.push_back( a ) ;
     39     head[u] = edge.size( ) - 1;
     40 }
     41 
     42 
     43 void link( int x , int y , int tote )
     44 {
     45     if( jv[x][y] == 2 )
     46     {
     47         add( 0 , tote , inf ) ;
     48         add( tote , 0 , 0 ) ;
     49     }
     50     int xx , yy , now ;
     51     for( int i = 0 ; i < 4 ; ++i  )
     52     {
     53         xx = x + sj[i][0] , yy = y + sj[i][1] , now = tote + sg[i] ;
     54         if( xx < 1 || yy < 1 || xx > n || yy > m ) continue ;
     55         if( jv[xx][yy] != 2 )
     56         {
     57             add( tote , now , 1 ) ;
     58             add( now , tote , 0 ) ;
     59         }
     60     }
     61 }
     62 
     63 
     64 void input(  )
     65 {
     66     n = read( ) , m = read( ) ; 
     67     tot = 0 ; cnt = -1 ;
     68     s = 0 , t = n * m + 1 ;
     69     sg[0] = 1 , sg[1] = -1 , sg[2] = m , sg[3] = 0 - m ;
     70     memset( head , -1 , sizeof(head) ) ;
     71     for( int x = 1 ; x <= n ; ++x )
     72         for( int y = 1 ; y <= m ; ++y )
     73             jv[x][y] = read( ) ;
     74     for( int x = 1 ; x <= n ; ++x )
     75         for( int y = 1 ; y <= m ; y ++ )
     76         {
     77             tot ++ ;
     78             if( jv[x][y] != 1 ) link( x , y , tot ) ;
     79             else 
     80             {
     81                 add( tot , t , inf ) ;
     82                 add( t , tot , 0 ) ;
     83             }
     84         }
     85 }
     86 
     87 
     88 bool bfs(  )
     89 {
     90     memset( dis , -1 , sizeof( dis ) ) ;
     91     dis[0] = 0 ; Q.push( 0 ) ;
     92     while( !Q.empty( ) )
     93     {
     94         int u = Q.front( )  ; Q.pop( ) ;
     95         for( int i = head[u] ; ~i ; i = edge[i].nxt )
     96         {
     97             int v = edge[i].to ;
     98             if( dis[v] < 0 && edge[i].val > 0 )
     99             {
    100                 dis[v] = dis[u] + 1 ;
    101                 Q.push( v ) ;
    102             }
    103         }
    104     }
    105     return dis[t] > 0 ;
    106 }
    107 
    108 
    109 int dfs( int u , int tmp )
    110 {
    111     if( u == t ) return tmp ;
    112     int an = 0 , cost = 0 ;
    113     for( int i = cur[u] ; ~i ; i = edge[i].nxt )
    114     {
    115         int v = edge[i].to ;
    116         if( dis[v] != dis[u] + 1  ) continue ;
    117         an = dfs( v , min( tmp -cost , edge[i].val ) ) ;
    118         edge[i].val -= an ; edge[i^1].val += an ; cost += an;
    119         if( edge[i].val ) cur[u] = i ;
    120         if( tmp == cost ) return cost ;
    121     } 
    122     if( !cost ) dis[u] = -1 ;
    123     return cost ;
    124 }
    125 
    126 
    127 void sov( )
    128 {
    129     while( bfs( ) )
    130     {
    131         for( int  i = 0 ; i <= t ; i++ ) cur[i] = head[i] ;
    132         ans +=dfs( 0 , inf ) ;
    133     }
    134     printf( "%d
    " , ans ) ;
    135 }
    136 
    137 
    138 int main( )
    139 {
    140 //    Init( ) ;
    141     input( ) ;
    142     sov( ) ;
    143 //    fclose( stdin ) ;
    144 //    fclose( stdout ) ;
    145     return 0 ;
    146 }
  • 相关阅读:
    Android EditText内容监听
    Android模仿QQ空间图片上传——原理
    PHP新手入门1——表单
    linux下ftp常用命令
    TextView所有属性
    iOS开发-删除字典中的null
    去除导航栏下方的横线
    应用的启动视图 LauchView
    App所需申请资料
    应用本地化
  • 原文地址:https://www.cnblogs.com/Ateisti/p/5930753.html
Copyright © 2020-2023  润新知