LGOJ3101 [USACO14JAN] ski level Ski Course Rating

LGOJ3101 [USACO14JAN] ski level Ski Course Rating


 

【Problem Description】

The cross-country skiing course at the winter Moolympics is described by an M x N grid of elevations (1 <= M,N <= 500), each elevation being in the range 0 .. 1,000,000,000.

Some of the cells in this grid are designated as starting points for the course. The organizers of the Moolympics want to assign a difficulty rating to each starting point. The difficulty level of a starting point P should be the minimum possible value of D such that a cow can successfully reach at least T total cells of the grid (1 <= T <= MN), if she starts at P and can only move from cell to adjacent cell if the absolute difference in elevation between the cells is at most D. Two cells are adjacent if one is directly north, south, east, or west of the other.

Please help the organizers compute the difficulty rating for each starting point.

Ski altitude represented by a M * N (1 <= M, N <= 500) matrix of numbers, each number represents the height in a range of 0 .. 1,000,000,000. Some grid is designated as a starting point, the organizers would like to do Difficulty rating on the starting point.

If the point P is a starting point for the level of difficulty starting point D, then D must be a minimum of the following conditions are met:

(1) can slide from one adjacent lattice grid;

(2) difference in elevation of not more than two lattice D;

(3) capable of at least reach the T (1 <= T <= M * N) lattice (including the starting point itself).

[Sample input]

3 5 10
20 21 18 99 5
19 22 20 16 17
18 17 40 60 80
1 0 0 0 0
0 0 0 0 0
0 0 0 0 1

[Sample Output]

24


 

#include <bits / STDC ++ H.>
 the using  namespace STD;
 const  int MAXN = 500 + . 5 ;
 const  int MAXM MAXN * = MAXN;
 Long  Long AM [MAXM], FA [MAXM], IS [MAXM];
 // AM AMOUNT the number of sub-set points, fa father parent node ID, is is_start starting point within the set number of 
Long  Long of He [MAXN] [MAXN], ID [MAXN] [MAXN];
 // of He height (I, J) height   
Long  Long n- , m, T, CNTV, Sign, CNTE;
 // CNTV count_vertex, CNTE count_edge   
struct Edge 
{ 
    Long  LongBEG, to, len; // BEG start point, to the end, len right side 
} A [ 1000000 ]; // tragic (need to open 1000000) 
Edge MK ( Long  Long X, Long  Long   Y, Long  Long Z) 
{ 
    Edge T = (edge) 
    { 
        X, Y, Z 
    }; 
    return T; 
} // this is a function of making the edge 
BOOL CMP (edge a, edge B) 
{ 
    return a.len < b.len; 
} // this is a the sorting function side (to serve the greedy idea) 
Long  Long the Find ( Long  LongX) 
{ 
    IF (FA == X [X]) return X;
     the else  return FA [X] = find (FA [X]); 
} // disjoint-set standard find function 
void Merge ( int X, int Y) 
{ 
    IF (X < Y) the swap (X, Y); 

    FA [Y] = X; 
    AM [X] + = AM [Y];
   //   AM [Y] = 0; 
    IS [X] + = IS [Y] ; 
} // this is a combined function (to maintain the number of sub-sets of two points, the number of the starting point) 
int main () 
{ 
    Scanf ( " %% LLD LLD% LLD ", &n, &m, &t);

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            scanf("%lld", &he[i][j]);
            cntv++;
            id[i][j] = cntv;
            //给坐标为(i,j)的点编号 cntv
        }
    } 
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            scanf("%lld", &sign);

            if(sign)is[id[i][j]] = 1;//这个点是一个起点 

            if(i < n)
            {
                a[++cnte] = mk(id[i][j], id[i + 1][j], abs(he[i][j] - he[i + 1][j]));
            }

            if(j < m)
            {
                a[++cnte] = mk(id[i][j], id[i][j + 1], abs(he[i][j] - he[i][j + 1]));
            } 
            
            // build edge 
        } 
    } 

    Sort (A + . 1 , A + . 1 + CNTE, CMP); 
    
    // greedy 
     
    Long  Long ANS = 0 ; 

    for ( int I = . 1 ; I <= MAXM; I ++ ) 
    { 
        AM [I] = . 1 ; // I is a set of its own 
        FA [I] = I; 
    } 
    for ( int I = . 1 ; I <= CNTE; I ++ ) 
    { 
        int X = a [I] .beg;
        int Y = A [I] .to;
         int Z = A [I] .LEN;
         int FX = Find (X);
         int FY = Find (Y);
         IF (FX == FY) Continue ; 
        
        IF (AM [FX ] + AM [FY]> = T) 
        { 
            IF (AM [FX] <T) = Z * + ANS iS [FX];
             // if the number is less than a set of t, the edge of which is not counted.    
            IF (AM [FY] <T) = Z * + ANS IS [FY]; 
        } 

        Merge (FX, FY); 
    } 

    the printf ( " % LLD " , ANS);
     return  0;
}

 

Guess you like

Origin www.cnblogs.com/yangxuejian/p/10993576.html