POJ 2843 Cutting Cake 并查集

POJ 2843 Cutting Cake 并查集

思路:

这题目非常牛逼!是道月赛的题目!看完题目我就放弃了。。直接看解题报告。
解法果然牛逼!

解题报告链接在此:
http://acm.pku.edu.cn/JudgeOnline/images/contestreport/200606/G.htm

代码是照着解题报告写的,不过还是很烂,好像3000+ms,实在佩服那些1000ms内的神牛们!

#include  < stdio.h >

#define  MAX_N 1024

struct  queue_node  {
    
int y, x;
}
;

int   set [MAX_N][MAX_N], cut[MAX_N][MAX_N];
int  N, M;
int  left, top, right, bottom;

struct  queue_node queue[MAX_N  *  MAX_N];
int  head, tail;

inline 
int  find( int   * arr,  int  idx)
{
    
static int stk[MAX_N * MAX_N], sp;

    
for (sp = 0; arr[idx]; idx = arr[idx])
        stk[sp
++= idx;
    
for (sp--; sp >= 0; sp--)
        arr[stk[sp]] 
= idx;

    
return idx;
}


inline 
void  push( int  y,  int  x)
{
    
if (x < left || x > right || y < top || y > bottom)
        
return ;
    
if (cut[y][x])
        
return ;
    
    cut[y][x] 
= 1;
    
if (cut[y][x - 1&& cut[y][x + 1]) {
        
set[y][x] = x + 1;
        
set[y][x - 1= x + 1;
    }
 else if (cut[y][x - 1]) 
        
set[y][x - 1= x;
    
else if (cut[y][x + 1])
        
set[y][x] = x + 1;
    
    queue[tail].y 
= y;
    queue[tail].x 
= x;
    tail
++;
}


inline 
int  bfs( int  y,  int  x)
{
    x 
= find(set[y], x);
    
if (cut[y][x])
        x
++;
    
if (x > right)
        
return 0;

    head 
= tail = 0;
    push(y, x);
    
while (head != tail) {
        y 
= queue[head].y;
        x 
= queue[head].x;
        head
++;
        push(y 
- 1, x);
        push(y 
+ 1, x);
        push(y, x 
- 1);
        push(y, x 
+ 1);
    }


    
return 1;
}


int  main()
{
    
int i, j, ans;

    freopen(
"e:\\test\\in.txt""r", stdin);

    scanf(
"%d%d"&N, &M);
    
while (M--{
        scanf(
"%d%d%d%d"&left, &top, &right, &bottom);
        ans 
= 0;
        
for (i = top; i <= bottom; i++)
            
while (bfs(i, left))
                ans
++;
        printf(
"%d\n", ans);
    }


    
return 0;
}

你可能感兴趣的:(POJ 2843 Cutting Cake 并查集)