码迷,mamicode.com
首页 > 其他好文 > 详细

狼和羊的故事

时间:2016-10-04 18:33:02      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......”
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 }

 

狼和羊的故事

标签:

原文地址:http://www.cnblogs.com/Ateisti/p/5930753.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!