图论—青蛙问题
来源:互联网 发布:少女前线敌人数据 编辑:程序博客网 时间:2024/05/18 00:49
青蛙的邻居(Frogs' Neighborhood)
题目描述:
未名湖附近共有 n 个大小湖泊 L1,L2, ...,Ln(其中包括未名湖),每个湖泊Li 里住着一只青蛙
Fi(1≤i≤n)。如果湖泊Li 和Lj 之间有水路相连,则青蛙Fi 和Fj 互称为邻居。现在已知每只青蛙的
邻居数目 x1,x2, ...,xn,请你给出每两个湖泊之间的相连关系。
输入描述:
第一行是测试数据的组数 t( 0 ≤ t ≤ 20)。每组数据包括两行,第一行是整数n( 2 ≤n ≤ 10),
第二行是 n 个整数, x1,x2,...,xn(0 ≤ xi <n)。
未名湖附近共有 n 个大小湖泊 L1,L2, ...,Ln(其中包括未名湖),每个湖泊Li 里住着一只青蛙
Fi(1≤i≤n)。如果湖泊Li 和Lj 之间有水路相连,则青蛙Fi 和Fj 互称为邻居。现在已知每只青蛙的
邻居数目 x1,x2, ...,xn,请你给出每两个湖泊之间的相连关系。
输入描述:
第一行是测试数据的组数 t( 0 ≤ t ≤ 20)。每组数据包括两行,第一行是整数n( 2 ≤n ≤ 10),
第二行是 n 个整数, x1,x2,...,xn(0 ≤ xi <n)。
输出描述:
对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用n×n
的矩阵表示湖泊间的相邻关系,即如果湖泊 i与湖泊 j 之间有水路相连,则第i 行的第 j个数字为
第 1 章 图的基本概念及图的存储
- 13 -
1,否则为 0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。
相邻两组测试数据之间输出一个空行。
样例输入: 样例输出:
2
7
4 3 1 5 4 2 1
6
4 3 1 4 2 0
YES
0 1 1 1 1 0 0
1 0 0 1 1 0 0
1 0 0 0 0 0 0
1 1 0 0 1 1 1
1 1 0 1 0 1 0
0 0 0 1 1 0 0
0 0 0 1 0 0 0
NO
分析:
本题的意思实际上是给定一个非负整数序列,问是不是一个可图的序列,也就是说能不能根
据这个序列构造一个图。这需要根据 Havel-Hakimi定理(定理 1.2)中的方法来构图,并在构图
中判断是否出现了不合理的情形。有以下两种不合理的情形:
(1) 某次对剩下序列排序后,最大的度数(设为d1)超过了剩下的顶点数;
(2) 对最大度数后面的 d1 个度数各减1 后,出现了负数。
一旦出现了以上两种情形之一,即可判定该序列不是可图的。
如果一个序列是可图的,本题还要求输出构造得到的图的邻接矩阵,实现思路是:
(1) 为了确保顶点序号与输入时的度数顺序一致,特意声明了一个vertex 结构体,包含了顶点
的度和序号两个成员。
(2) 每次对剩下的顶点按度数从大到小的顺序排序后, 设最前面的顶点 (即当前度数最大的顶
点)序号为 i、度数为 d1,对后面d1 个顶点每个顶点(序号设为j)度数减 1,并连边,即在邻接
矩阵 Edge 中设置 Edge[i][j]和Edge[j][i]为1。
#include<stdio.h>#include<stdlib.h>#include<string.h>#define N 15struct vertex{int degree; //定点的度int index; //定点的序号 }v[N];int cmp(const void *a, const void *b){return ((vertex*)b)->degree - ((vertex*)a)->degree;}int main(){int r,k,p,q; //循环变量int i,j; //顶点序号(用于确定图中边的两个顶点) int d1; //对剩下序列排序后第1个顶点(度数最大的顶点)的度数 int T,n; //测试数据个数,湖泊个数 int Edge[N][N],flag; //邻接矩阵。是否存在合理相邻关系的标志 scanf("%d",&T);while(T--){scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&v[i].degree);v[i].index = i; //按输入顺序给每个湖泊编号 }memset(Edge,0,sizeof(Edge));flag = 1;for(k=0;k<n&&flag;k++){//对v数组后n-k个元素按非递增顺序排序 qsort(v+k,n-k,sizeof(vertex),cmp);i = v[k].index; //第k个顶点的序号 d1=v[k].degree;if(d1>n-k-1) flag = 0;for(r=1;r<=d1&&flag;r++){j=v[k+r].index; //后边d1个顶点每个顶点的序号 if(v[k+r].degree<=0) flag=0;v[k+r].degree--;Edge[i][j] = Edge[j][i] = 1;}}if(flag){puts("YES");for(p=0;p<n;p++){for(q=0;q<n;q++){if(q) printf(" ");printf("%d",Edge[p][q]);}puts("");}}else puts("NO");if(T) puts(""); } return 0;}
0 0
- 图论—青蛙问题
- 青蛙跳和变态青蛙跳问题
- 青蛙跳台阶问题
- 青蛙跳阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙跳台阶问题
- 青蛙过河的问题
- 青蛙换位置问题
- 青蛙跳台阶问题
- 青蛙跳台问题
- 青蛙跳台问题
- 青蛙跳台阶问题
- python读写文本文件-解决乱码问题
- Jquery中table数据的值拷贝及拆分
- Pixhawk开发手册
- 数据库索引分类
- phpstudy升级mysql数据库
- 图论—青蛙问题
- maven工程实战(1)
- 【SHOI 2002】百事世界杯之旅 (BSOI4841)
- LeetCode刷题【Array】 Subsets
- ubuntu16.04+git
- CJOJ 2403 次小生成树
- windows下jira系统的安装和破解注意事项
- iOS 字典JSON互相转换
- C/C++实现大整数加减法