cf#306-D - Regular Bridge- 构造 k度无向图

本文详细阐述了如何构造一个无向图,使得每个节点的度数为指定值k,并确保存在一条桥边将图分割成两部分。通过增加特定数量的节点和边,实现图的合法性验证。

题意:

给出一个k,表示一个无向图的每个节点的度数为k,并且在无向图中有一条边如果去掉之后会把这个无向图分成两个部分,也就是桥,要求输出任意合法的图

我们可以这样考虑,把图分成对称的两部分,两部分之间满足k度,最后两部分由一条边连接,这条边就可以称之为桥,因为只要去掉,整个图就变成2个联通块了。

思路:

我们先对 对称的左边部分考虑:

先假设有k个点,点k为桥的端点,那么他还需要与k-1个点相连。

我们把点k和   点1、2、3.....k-1都相连,现在点k满足了度数为k.

然后我们考虑发现点1、2、3.....k-1度数都为1, 并且 如果只有这几个点,无论如何都不能使得他们的度数全达到k,也就是说,要增加点。

如果我们先增加一个点k+1,我们可以给点1、2、3.....k-1的度数都增加1,那么对与增加了的点k+1他的度数只能达到k-1,也是不行的;

那么我们试试增加2个点,分别为k+1,k+2,把他们分别和点1、2、3.....k-1相连,然后再把k+1,k+2连在一起,发现k+1,k+2满足了度数为k,

与此同时,点1、2、3.....k-1的度数都增加2。

显然 ,由于点1、2、3.....k-1需要的度数为k-1,如果k-1为偶数,那么 我们只需要增加 【(k-1)/ 2】对 这样的点(k+1,k+2),就可以使得所有的点满足题意。

也就是k为奇数时,必然可以按这样的构造方法  使得  整个左边部分合法。

【点与边的数量】

一开始有k个点,为了满足条件,我们需要增加k-1对点,也就是多了(k-1),总共2k-1,由于对称,总共4k-2个点,

边的话,最后把所有构造数的边数一下就好。

构造过程用vector储存边

PS: 。。不知道怎么严格证明偶数点是不合法的...怎么也构造不了偶数的图。。。

参考自http://blog.youkuaiyun.com/libin56842/article/details/46427673


以下是代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;  
vector<int> sb[4*100];
int main()
{

	int n; 
	scanf("%d",&n); 
	if (n%2==0)
	{
		printf("NO\n");
		return 0;
	} 
	int i,j; 
	 int v=4*n-2;
	for (i=1;i<=n-1;i++)
	{
		sb[n].push_back(i);
	} 
	for (i=1;i<=n-1;i++)
	{
		for (j=n+1;j<=2*n-1;j++)
		{
			sb[j].push_back(i);
		}
	}
	for(j=n+1;j<=2*n-1;j+=2)
	{
		 sb[j].push_back(j+1);
	}

	for (i=1;i<=2*n-1;i++)			//这个是把1到v/2的点与边对称到v/2+1到v
	{	
		for (j=0;j<sb[i].size();j++)
		{ 
			sb[v/2+i].push_back(v/2+sb[i][j]);
		}
	
	}

	int sum_edge=0;
	for (i=1;i<=2*n-1;i++)
	{
		 sum_edge+=sb[i].size();
	}

	printf("YES\n");
	printf("%d %d\n",v,sum_edge*2+1);

	printf("%d %d\n",n,v/2+n);
	for (i=1;i<=v;i++)
	{
		for (j=0;j<sb[i].size();j++)
			printf("%d %d\n",i,sb[i][j]);
	}
	

	   return 0;
	   
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值