• 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
    " , 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
    " , 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)
    " , 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
    " , cas ++ , d[st]) ;
    121     }
    122     return 0 ;
    123 }
    View Code

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

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

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

    然后套套dijkstra模板过了。

  • 相关阅读:
    Android SD卡读写文件
    Android 是什么
    Canvas 类
    Java IO流之字节流 FileInputStream
    Android中asset文件夹和raw文件夹区别
    随手收藏
    Java IO流
    Android私有文件资源文件的存取
    ubuntu 下的jdk安装
    Paint类
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4464168.html
Copyright © 2020-2023  润新知