题意:
给出一个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;
}

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

被折叠的 条评论
为什么被折叠?



