#306 (div.2) D. Regular Bridge
2015-06-09 18:52
441 查看
1.题目描述:点击打开链接
2.解题思路:本题属于一道图论的构造题。要求构造出一张无向图,其中所有的顶点的度数均为k,且至少含有一个桥。这道题在比赛时候没有任何思路,因为始终想象不出来k>1的情况。比赛结束后终于尝试画出了k=3的情况。然后摸索出来了做题方法。
首先,对于k等于偶数的情况,一定是不存在解的。假设顶点0是桥的一个端点,那么将桥断开后,它和所在的连通分量的2m-1个点相连(设k=2m),那么这2m-1个点需要再和2m-1个点相连接。假设这令外的2m-1个点都是新的点,那么这批点的度数将成为2m-1,之后需要两两相连,然而此时只有奇数个点,一定有一个点没办法配对,不满足度数等于k的条件。如果连接的点涉及第一批这2m-1个点,仍然会导出有一个点无法匹配的情况。
那么,当k为奇数的时候,只需要按照上述的方法进行构造,就一定可以保证得到合法的无向图。即:第一步,将0和2k-1设置为桥的两个端点。他们相连。第二步,0结点和1到k-1这k-1个点相连接。第三步,1结点到k-1个点分别伸出k-1条边和k到2k-2这k-1条边相连接。第四步,结点k到2k-2这k-1条边两两配对(注意此时k-1是偶数)。用同样的方法处理结点2k-1,即可构造出完整的图。
3.代码:
2.解题思路:本题属于一道图论的构造题。要求构造出一张无向图,其中所有的顶点的度数均为k,且至少含有一个桥。这道题在比赛时候没有任何思路,因为始终想象不出来k>1的情况。比赛结束后终于尝试画出了k=3的情况。然后摸索出来了做题方法。
首先,对于k等于偶数的情况,一定是不存在解的。假设顶点0是桥的一个端点,那么将桥断开后,它和所在的连通分量的2m-1个点相连(设k=2m),那么这2m-1个点需要再和2m-1个点相连接。假设这令外的2m-1个点都是新的点,那么这批点的度数将成为2m-1,之后需要两两相连,然而此时只有奇数个点,一定有一个点没办法配对,不满足度数等于k的条件。如果连接的点涉及第一批这2m-1个点,仍然会导出有一个点无法匹配的情况。
那么,当k为奇数的时候,只需要按照上述的方法进行构造,就一定可以保证得到合法的无向图。即:第一步,将0和2k-1设置为桥的两个端点。他们相连。第二步,0结点和1到k-1这k-1个点相连接。第三步,1结点到k-1个点分别伸出k-1条边和k到2k-2这k-1条边相连接。第四步,结点k到2k-2这k-1条边两两配对(注意此时k-1是偶数)。用同样的方法处理结点2k-1,即可构造出完整的图。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; typedef long long ll; typedef unsigned long long ull; #define me(s) memset(s,0,sizeof(s)) #define For(i,n) for(int i=0;i<(n);i++) #define pb push_back #define sz size #define clr clear #define F(a,b) for(int i=a;b;i++) const int N=500; vector<int>g ; int k; void addedge(int m) { for(int i=1;i<=k-1;i++)//第二步 g[m+0].pb(m+i); for(int i=1;i<=k-1;i++) for(int j=1;j<=k-1;j++)//第三步 g[m+i].pb(m+k-1+j); for(int j=1;j<k-1;j+=2)//第四步 g[m+k-1+j].pb(m+k+j); } int main() { // freopen("t.txt","r",stdin); while(~scanf("%d",&k)) { memset(g,0,sizeof(g)); if(k&1) { puts("YES"); int n=2*(2*k-1); int m=2*k*k-k; printf("%d %d\n",n,m); g[0].pb(2*k-1);//第一步 addedge(0); addedge(2*k-1); for(int i=0;i<2*k-1;i++) { int len=g[i].size(); for(int j=0;j<len;j++) printf("%d %d\n",i+1,g[i][j]+1); } for(int i=0;i<2*k-1;i++) { int len=g[i+2*k-1].size(); for(int j=0;j<len;j++) printf("%d %d\n",i+2*k,g[i+2*k-1][j]+1); } } else puts("NO"); } return 0; }
相关文章推荐
- 软键盘问题
- 硬盘分区Convert转换为NTFS后使用正常,但DiskGenius显示未格式化的解决方法
- 都是为了生活
- 【app运营 】一款APP产品如何拉新、留存用户?
- 博士这条船(留美博士生写给后来人的辛酸回忆:你适合读博士和搞科研吗?在选择继续读研、读博的这条路上,你准备好了吗?)
- 菜鸟学排序算法
- Ubuntu 14.04中安装Java
- SQLyog键盘快捷方式
- SQLyog键盘快捷方式
- Javascript 中判断对象为空
- oracle 主键 外键
- 分享:我做产品的时候,会想些什么?
- POJ1006 Biorhythms 中国剩余定理
- java.lang.io包的使用
- 那什么,想计算日期,datetime搞起
- 推荐!国外程序员整理的Java资源大全
- [IIS] Windows Server 2012 R2 + IIS8.5碰到的一些问题
- web页面通过ajax无限下拉
- .net 一些常用的工具来破解
- log4j 格式详解