题意:一个图,图的每个顶点度数都为k,问这个图中是否可能含有割边。有救输出图,无NO。
思路:
假设存在度数为k 的这样一个图,利用对称的思想,去掉割边后得到两个完全相同的子图。子图顶点数为n,则子图的总度数为n*k-1,因总度数必为偶数,故n,k都为奇数。
然后构图就要看你脑洞有多大了。
我是这样做的,度为k-1的点s与k-1个点相连。再令设两点i、j,都与那k-1个点相连,
这样i、j的度为k-1了,再让i、j相连,除那k-1个点,其他的点都满足要求了。
而这k-1个点每个点的度数都差k-3度。怎么办?
把这k-1个点想成一个正k-1边形,除了对角线上的点不相连,其余的都连上,这样就完全满足要求了。
代码写的并不是很好。。。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 1005;
int k;
vector<int> G[maxn];
bool mark[maxn];
void add_Edge(int from,int to){
G[from].push_back(to);
G[to].push_back(from);
}
int main(){
memset(mark,0,sizeof(mark));
scanf("%d",&k);
if(k % 2 == 0) printf("NO\n");
else{
if(k == 1){
printf("YES\n2 1\n1 2\n");
}else{
printf("YES\n");
printf("%d %d\n",2*k+4,k*(k+2));
add_Edge(0,k+2);
add_Edge(k,k+1);
add_Edge(2*k+2,2*k+3);
for(int i=1;i<=k-1;i++){
add_Edge(0,i);add_Edge(k,i); add_Edge(k+1,i);
}
for(int i=k+3;i<=2*k+1;i++) {
add_Edge(k+2,i); add_Edge(2*k+2,i); add_Edge(2*k+3,i);
}
if(k > 3){
for(int i=1;i<=k-1;i++){
for(int j=1;j<=k-1;j++){
if(i == j || 2*abs(i - j) == k-1) continue;
add_Edge(i,j);
}
}
for(int i=k+3;i<=2*k+1;i++){
for(int j=k+3;j<=2*k+1;j++){
if(i == j || 2*abs(i - j) == k-1) continue;
add_Edge(i,j);
}
}
}
for(int i=0;i<=2*k+3;i++){
sort(G[i].begin(),G[i].end());
G[i].erase(unique(G[i].begin(),G[i].end()),G[i].end());
mark[i] = true;
for(int j=0;j<G[i].size();j++){
int v = G[i][j];
if(!mark[v]) printf("%d %d\n",i+1,v+1);
}
}
}
}
return 0;
}