首页 > 代码库 > 狼和羊的故事

狼和羊的故事

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......”
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\n" , ans ) ;135 }136 137 138 int main( )139 {140 //    Init( ) ;141     input( ) ;142     sov( ) ;143 //    fclose( stdin ) ;144 //    fclose( stdout ) ;145     return 0 ;146 }

 

狼和羊的故事