UVA1376.Animal Run (最小割转为最短路 && dijkstra)

Animal Run
Time Limit:6000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu

Description

Download as PDF
 

Animals are living their painful lives in the zoo. Their activities are limited in a small area without any fun of snacks, alcohol, love or games. They are so upset that they decide to escape in a night.

As shown in Figure 1, the paths in the zoo can be expressed by a grid with nxm nodes. All the paths in the grid are two-way, horizontal or vertical or diagonal. Animals start from the upper left corner, and they are free if they can reach the lower right through paths.

 

\epsfbox{p3661.eps}

 

Figure 1: This is a 3 x 4 nodes grid, the number beside the path indicating how many staff shall be sent to block this path

To protect public safety, the police are sent to block some paths to catch all the escaping animals. As it needs certain police staff to block a path, you are required to write a program for the police officer, and tell him how many staff at least shall be sent in order to defeat this Animal Escape.

 

Input

Input contains several cases, each describes one escape action.

Each case begins with two integers n and m, 3 $ \leq$n, m$ \leq$ 1000.

For the following n lines, there are m - 1 integers in each line, indicating how many staff shall be sent to block the horizontal paths respectively.

For the following n - 1 lines, there are m integers in each line, indicating how many staff shall be sent to block the vertical paths respectively.

For the following n - 1 lines, there are m - 1 integers in each line, indicating how many staff shall be sent to block the diagonal paths respectively.

Each line describes the paths from left to right. All integers in input file are no more than 1, 000, 000.

The last case is followed by a line containing two zeros. The size of the input data is about 16MB.

 

Output

For each case, output how many staff at least shall be sent to block all animals. Please output in the following format.

 

Sample Input

3 4
5 6 4
4 3 1
7 5 3
5 6 7 8
8 7 6 5
5 5 5
6 6 6
0 0

 

Sample Output

 

Case 1: Minimum = 14
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #include<algorithm>
  5 typedef long long ll ;
  6 const int M = 1000 + 5 ;
  7 const int maxn = 1005*1005*3   ;
  8 int hori[M][M] , vert[M][M] , diag[M][M] ;
  9 int st , ed ;
 10 const int inf = 0x3f3f3f3f ;
 11 struct edge
 12 {
 13     int u , v , w ;
 14 };
 15 
 16 struct heapnode
 17 {
 18     ll d , u ;
 19     bool operator < (const heapnode & rhs ) const
 20     {
 21         return d > rhs.d ;
 22     }
 23 };
 24 
 25 int n , m ;
 26 std::vector <edge> edges ;
 27 std::vector <int> g[maxn] ;
 28 bool done[maxn] ;
 29 ll d[maxn] ;
 30 int p[maxn] ;
 31 
 32 void init (int n)
 33 {
 34     for (int i = 0 ; i <= n ; i ++ ) g[i].clear ();
 35     edges.clear () ;
 36 }
 37 
 38 void addedge (int u , int v , int w)
 39 {
 40     edges.push_back ( (edge) {u , v , w}) ;
 41     int m = edges.size () ;
 42     g[u].push_back (m - 1) ;
 43 }
 44 
 45 void dijkstra (int s)
 46 {
 47     std::priority_queue <heapnode> q ;
 48     for (int i = 0 ; i <= ed ; i ++) d[i] = inf ;
 49     d[s] = 0 ;
 50     memset (done , 0 , sizeof(done))  ;
 51     q.push ( (heapnode) {0 , s}) ;
 52     while ( !q.empty ()) {
 53         heapnode x = q.top () ; q.pop () ;
 54         int u = x.u ;
 55         if (done[u]) continue ;
 56         done[u] = true ;
 57         for (int i = 0 ; i < g[u].size () ; i ++) {
 58             edge e = edges[g[u][i]] ;
 59            // printf ("%d > %d + %d\n" , d[e.v] , d[u] , e.w ) ;
 60             if ( d[e.v] > d[u] + e.w ) {
 61                 d[e.v] = d[u] + 1ll * e.w ;
 62                 p[e.v] = g[u][i] ;
 63                 q.push ( (heapnode) {d[e.v] , e.v }) ;
 64             }
 65         }
 66     }
 67 }
 68 
 69 void build ()
 70 {
 71     for (int i = 0 ; i < n - 1 ; i ++) {
 72         for (int j = 0 ; j < m - 1 ; j ++) {
 73             int u = i * 2 * (m - 1) + 2 * j , v = i * 2 * (m - 1) + 2 * j + 1 ;
 74             addedge (u , v , diag[i][j]) ;
 75             addedge(v , u , diag[i][j]) ;
 76           //  printf ("m=%d\n" , m ) ;
 77         }
 78     }
 79     for (int i = 1 ; i < n - 1; i ++) {
 80         for (int j = 0 ; j < m - 1 ; j ++) {
 81             int u = (i - 1) * 2 * (m - 1)+ 2 * j , v = i * 2 * (m - 1)+ 2 * j + 1 ;
 82             addedge (u , v , hori[i][j]) ;
 83             addedge (v , u , hori[i][j]) ;
 84         }
 85     }
 86     for (int j = 0 ; j < m - 1 ; j ++) {
 87         addedge (2 * j + 1 , st , hori[0][j]) ;
 88         addedge (ed , (n - 2 ) * 2 * (m - 1) + 2 * j , hori[n - 1][j]) ;
 89     }
 90     for (int i = 0 ; i < n - 1 ; i ++) {
 91         for (int j = 1 ; j < m - 1 ; j ++) {
 92             int u = i * 2 * (m - 1) + 2 * j - 1, v = i * 2 * (m - 1 ) + 2 * j  ;
 93             addedge (u , v , vert[i][j]) ;
 94             addedge (v , u , vert[i][j]) ;
 95         }
 96     }
 97     for (int i = 0 ; i < n - 1 ; i ++) {
 98         addedge (ed , i * 2 * (m - 1 ), vert[i][0] ) ;
 99         addedge ((i + 1) * 2 * (m - 1) - 1 , st , vert[i][m - 1]) ;
100     }
101    // for (int i = 0 ; i < edges.size () ; i ++) printf ("%d--->%d(%d)\n" , edges[i].u , edges[i].v , edges[i].w ) ;
102 }
103 
104 int main ()
105 {
106    // freopen ("a.txt" , "r" , stdin ) ;
107    int cas = 1 ;
108     while (~ scanf ("%d%d" , &n , &m ) ) {
109         if (n == 0 && m == 0) break ;
110         st = (n - 1) * 2 * (m - 1)  ; ed = (n - 1) * 2 * (m - 1) + 1 ;//源点 , 汇点
111         int rhs = std::max (n , m ) ;
112         init (3 * rhs * rhs ) ;
113         for (int i = 0 ; i < n; i ++) for (int j = 0 ; j < m - 1 ; j ++) scanf ("%d" , &hori[i][j]) ;
114         for (int i = 0 ; i < n - 1 ; i ++) for (int j = 0 ; j < m ; j ++) scanf ("%d" , &vert[i][j]) ;
115         for (int i = 0 ; i < n - 1 ; i ++) for (int j = 0 ; j < m - 1 ; j ++) scanf ("%d" , &diag[i][j]) ;
116         build () ;
117         dijkstra (ed) ;
118       //  for (int i = 0 ; i <= ed ; i ++) printf ("%2d ", i) ; puts ("") ;
119       //  for (int i = 0 ; i <= ed ; i ++) printf ("%2d " , d[i]) ; puts ("") ;
120         printf ("Case %d: Minimum = %lld\n" , cas ++ , d[st]) ;
121     }
122     return 0 ;
123 }
View Code

建图真心好难,一开始一直在yy怎么设点:比如说一个个命名 ,先把数据存图 , 再在图上搜相邻点间的关系。。。但结果感觉都非常奇怪。

后来想到了一个出路,就是他给的数据存到hori[][] , vert[][] , diag[][] .

然后用i , j来表示一个个三角形的下标。并分别将以上三种边相邻的三角形建立关系。

然后套套dijkstra模板过了。

posted @ 2015-04-28 21:54  92度的苍蓝  阅读(256)  评论(0编辑  收藏  举报
http://images.cnblogs.com/cnblogs_com/Running-Time/724426/o_b74124f376fc157f352acc88.jpg