题目大意:中文
注释代码:
/*
* Problem ID : POJ 1659 Frogs' Neighborhood
* Author : Lirx.t.Una
* Language : C++
* Run Time : 0 ms
* Run Memory : 132 KB
*/
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
//最大点数
#define MAXN 10
using namespace std;
//思路:本题是根据无向图中点的度数求原图
//实际为拓扑排序的逆过程
struct Node {//表示每个点
char id;//记录每个点的序号
char deg;//点的度数
bool//对点按照从大到小排列
operator<(const Node &oth)
const {
return deg > oth.deg;
}
};
Node node[MAXN];//点
bool g[MAXN][MAXN];//原图
bool
toplink(int n) {//拓扑连接,为拓扑排序的逆过程
int i, j;//计数变量
int deg;//临时度数变量
for ( i = 0; i < n; i++ ) {
//每跟新一次度数就重排一次,重排的起始点为上次摘掉的点的后面一个位置
//前面的点由于度数都分配完了,因此就没有考虑的必要了
sort(node + i, node + n);
//这就是按照度数从大到小排的原因了,如果当前点的度数比剩余点数都多
//这就说明度数无法分配完,这种情况必定是不允许的,因为两点之间不能有超过1条边
if ( ( deg = node[i].deg ) > n - i - 1 ) return false;
if ( !deg ) return true;//表示入度已经全部分配完,因为是按照入度从大到小排列的
//因此当前点度为0就意味着后面的点度也必定为0,也就代表多有点的度都为0了
//就表示度数已经分配完了
for ( j = i + 1; j <= i + deg; j++ ) {//由于是从头到尾遍历跟新度数的,因此按照
//度数从大到小排列可以是入度分配地更加快从而加速算法,当然从小到大排算法也是
//一样的,就是速度不如从大到小来的快
if ( !node[j].deg ) return false;//但是后面的点的度数不够此次分配也将导致失败
node[j].deg--;//跟新并连边
g[ node[i].id ][ node[j].id ] = true;
g[ node[j].id ][ node[i].id ] = true;
}
node[i].deg = 0;//当前点度数分配完就置0
}
return true;
}
int
main() {
int t;//测例数
int n;//点数
int i, j;//计数变量
scanf("%d", &t);
while ( t-- ) {
memset(g, false, sizeof(g));
scanf("%d", &n);
for ( i = 0; i < n; i++ ) {
node[i].id = i;
scanf("%d", &node[i].deg);
}
if ( !toplink(n) )
puts("NO");
else {
puts("YES");
for ( i = 0; i < n; putchar('\n'), i++ )
for ( j = 0; j < n; j++ )
printf("%d ", g[i][j]);
}
putchar('\n');
}
return 0;
}
无注释代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define MAXN 10
using namespace std;
struct Node {
char id;
char deg;
bool
operator<(const Node &oth)
const {
return deg > oth.deg;
}
};
Node node[MAXN];
bool g[MAXN][MAXN];
bool
toplink(int n) {
int i, j;
int deg;
for ( i = 0; i < n; i++ ) {
sort(node + i, node + n);
if ( ( deg = node[i].deg ) > n - i - 1 ) return false;
if ( !deg ) return true;
for ( j = i + 1; j <= i + deg; j++ ) {
if ( !node[j].deg ) return false;
node[j].deg--;
g[ node[i].id ][ node[j].id ] = true;
g[ node[j].id ][ node[i].id ] = true;
}
node[i].deg = 0;
}
return true;
}
int
main() {
int t;
int n;
int i, j;
scanf("%d", &t);
while ( t-- ) {
memset(g, false, sizeof(g));
scanf("%d", &n);
for ( i = 0; i < n; i++ ) {
node[i].id = i;
scanf("%d", &node[i].deg);
}
if ( !toplink(n) )
puts("NO");
else {
puts("YES");
for ( i = 0; i < n; putchar('\n'), i++ )
for ( j = 0; j < n; j++ )
printf("%d ", g[i][j]);
}
putchar('\n');
}
return 0;
}