新手赛正赛热身题,当时不会做,连最少生成树是什么都不知道。后来上完课才知道这个算法,时隔多天后于寒假时做出来的……
总之就是,Prim最小生成树,保险起见还用了优先队列,其余的无需多讲。
Run Time: 0sec
Run Memory: 304KB
Code length: 1672Bytes
SubmitTime: 2012-01-26 17:13:23
// Problem#: 4421
// Submission#: 1200060
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <queue>
using namespace std;
int dirt[ 4 ][ 2 ] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
struct Pos {
int x, y;
int value;
Pos() { x = 0; y = 0; value = 0; }
friend bool operator < ( const Pos& p1, const Pos& p2 ) { return p1.value > p2.value; }
};
int square( int n ) { return n * n; }
int main()
{
int i, j;
int T, R, C;
int rooms[ 51 ][ 51 ];
bool visited[ 51 ][ 51 ];
Pos add, temp;
int count, sum;
scanf( "%d", &T );
while ( T-- ) {
scanf( "%d%d", &R, &C );
for ( i = 1; i <= R; i++ ) {
for ( j = 1; j <= C; j++ ) {
visited[ i ][ j ] = false;
scanf( "%d", &rooms[ i ][ j ] );
if ( rooms[ i ][ j ] == 0 ) {
add.x = i;
add.y = j;
}
}
}
priority_queue<Pos> q;
sum = 0;
for ( count = 1; count < R * C; count++ ) {
visited[ add.x ][ add.y ] = true;
for ( i = 0; i < 4; i++ ) {
temp.x = add.x + dirt[ i ][ 0 ];
temp.y = add.y + dirt[ i ][ 1 ];
if ( temp.x >= 1 && temp.x <= R && temp.y >= 1 && temp.y <= C ) {
temp.value = square( rooms[ add.x ][ add.y ] - rooms[ temp.x ][ temp.y ] );
q.push( temp );
}
}
add = q.top();
while ( visited[ add.x ][ add.y ] ) {
q.pop();
add = q.top();
}
sum += add.value;
q.pop();
}
printf( "%d\n", sum );
}
return 0;
}