您的位置:首页 > 其它

poj Frogs' Neighborhood(1659)

2014-08-14 16:05 507 查看
Frogs' Neighborhood

Time Limit: 5000MSMemory Limit: 10000K
Total Submissions: 7293Accepted: 3149Special Judge
Description

未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N)。如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居。现在已知每只青蛙的邻居数目x1, x2,
..., xn,请你给出每两个湖泊之间的相连关系。

Input

第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N)。

Output

对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用N×N的矩阵表示湖泊间的相邻关系,即如果湖泊i与湖泊j之间有水路相连,则第i行的第j个数字为1,否则为0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。

Sample Input
3
7
4 3 1 5 4 2 1
6
4 3 1 4 2 0
6
2 3 1 1 2 1

Sample Output
YES
0 1 0 1 1 0 1
1 0 0 1 1 0 0
0 0 0 1 0 0 0
1 1 1 0 1 1 0
1 1 0 1 0 1 0
0 0 0 1 1 0 0
1 0 0 0 0 0 0

NO

YES
0 1 0 0 1 0
1 0 0 1 1 0
0 0 0 0 0 1
0 1 0 0 0 0
1 1 0 0 0 0
0 0 1 0 0 0

题目大意:
给定一个图的度序列,判断这个图是否可图,如可图,用矩阵表示一种可图图(不唯一,任一即可)。

题目分折:

根据 Havel-Hakimi 定理。

每次对剩下的顶点按度从大到小排序,(最大的度数 di 超过了剩下的顶点数,则不可图),去除最大的,对于后面的 di 个数分别减一,(如果出现小于零的度,则不可图)

我们借助于一个结构体保存 度数,原序列号。用一个mat[][] 数组记录连通关系。简直就成了模拟题(倒也是模拟题)。

题目链接:http://poj.org/problem?id=1659

小乐一下:

有很多题的解是不具有唯一性的,碰到这样的问题,只要自己的思路对,代码没有错,就不会错。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node{
int greed;
int id;
}node[20];
int mat[20][20];
int N;
bool cmp(Node a,Node b){return a.greed > b.greed ;}  //按度从大到小排序。

int main(){
int i,j;
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
for(i = 1;i<=N;i++) {
scanf("%d",&node[i].greed);
node[i].id = i;
}
bool flag = true;
memset(mat,0,sizeof(mat));
for(i = 1;i<=N && flag;i++){
sort(node+i,node+1+N,cmp);
if(node[i].greed>N-i){  //如果度数大于剩下顶点个数,不可图。
flag = false;
break;
}
for(j = 1;j<=node[i].greed;j++){
int a = node[i].id;
int b = node[i+j].id;
mat[a][b] = mat[b][a] = 1;
node[i+j].greed --;
if(node[i+j].greed<0){ //出现了负数,不可图。
flag = false;
break;
}
}
}
if(flag){
printf("YES\n");
for(i = 1;i<=N;i++){
int first = 1;
for(j = 1;j<=N;j++) {
if(first) {printf("%d",mat[i][j]);first = 0;}
else printf(" %d",mat[i][j]);
}
printf("\n");
}
printf("\n");
}
else printf("NO\n\n");
}
return 0;
}


伟大的梦想成就伟大的人,从细节做好,从点点滴滴做好,从认真做好。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: