一、问题描述
京东的题目
给定一张包含N个点、M条边的无向图,每条边连接两个不同的点,且任意两点间最多只有一条边。对于这样的简单无向图,如果能将所有点划分成若干个集合,使得任意两个同一集合内的点之间没有边相连,任意两个不同集合内的点之间有边相连,则称该图为完全多部图。现在你需要判断给定的图是否为完全多部图。
输入:第一行输入一个整数T表示数据组数,1≤T≤10。每组数据格式为:第一行包含两个整数N和M,1≤N≤1000,0≤M≤N(N-1)/2;接下来M行,每行包含两个整数X和Y,表示第X个点和第Y个点之间有一条边,1≤X,Y≤N。每组输出占一行,如果给定的图为完全多部图,输出Yes,否则输出No。
二、思路
问了问本科的ACM大神,他给的思路是利用补图的概念:
1、通过题目已知:没有边的两个点一定在同一个集合内;
2、求此完全多部图相对于完全图的补图(此补图中,存在边的两个点属于同一集合);
3、遍历步骤2中的补图,将相连的结点放在同一个集合中;
4、计算步骤3中得到的集合之间边的总和,是否和给定的图中边数相同,相同则为yes,否则为No。
三、具体实现
1.图的连接关系:
用二维数组实现,数组规模为点的个数+1的平方,加一是为了略过数组下标为0的情况,因为所有给的点的标号都是从1开始的。
数组的行为对应点的标号,数组列也对应点的标号,我们根据京东给出的已知条件,可以将数组做如下初始化:
条件:
京东给了两个图,第一个是5个点7条边,然后继续点的连接的关系为1-3,1-5,2-3,2-5,3-4,4-5,3-5;第二个是4个点3条边,点的连接关系为1-2,2-3,3-4。
我们以第一个是完全多部图的图为例子,初始化二维数组来建立图的点连接关系。
//输入边的关系,并对数组进行初始化,相连的边对应的二维数组元素设置为1
for (int i = 0; i <M;i++) {
int row = scan.nextInt();
int wid = scan.nextInt();
a[row][wid]=1;
a[wid][row]=1;
}