Codeforces Gym 100431A Achromatic Number 欧拉回路
原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-andrew-stankevich-contest-37-asc-37-en.pdf
题意
给你一个n,让你构造一个环,使得相邻的节点的颜色不一样,问最多能使用多少颜色,并且输出染色方案。
题解
首先,我们来考察对于k个颜色,我们至少需要多少节点。每个点可以连接两个点,将边考虑为有向边,如果我们不浪费任何一条边,对于一个颜色,我们将它连到其余的一半的颜色,将另外一半的颜色连接到他,由于可能除不尽,所以要向上取整。这样,我们得到了一个简单的公式,对于偶数的颜色k,我们需要k*k/2的点,对于奇数的颜色k,我们需要k*(k-1)/2的点。
现在反过来思考,对于给定的节点数,我们至少需要多少颜色。如果刚刚够用,自然最好,如若不然,就寻找一个合适的k,然后采取在多于的节点随便染色的策略。但事实并非如此,因为题意要求是个环,那么我们如若在最后补颜色,那么就会拆开最后一条边,所以,如果给的n只比合适值多1,那么颜色数就要减一,这就是为什么4个点的答案是2而3个点的答案是3。
接下来,我们来考虑如何构造解。对于我们已经构建好的有向图,本质上是要遍历所有的边。那么只需要在最初弄好的颜色的有向图上跑一发欧拉回路。然后我们需要填充多于的节点,为了避免出现拆开唯一的颜色边,所以应当将一个重复的边拆开,再在里面插点。插点时需要满足题意的条件。
此题坑非常多,需要十分细致,最好手算一下前10的答案,然后比对一下输出。
代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
#define MAX_N 1234
using namespace std; int gao[MAX_N];
int k;
struct edge
{
bool vis;
int to;
edge(int t)
:vis(),to(t){}
edge(){}
}; vector<edge> G[MAX_N];
int tot=,road[MAX_N];
bool flag=false;
int n; int st[MAX_N],all=; void dfs(int u) {
//cout<<u<<endl;
int i = gao[u];
while (i < G[u].size() && G[u][i].vis)i++;
if (i == G[u].size())return;
gao[u] = i + ;
G[u][i].vis = ;
st[all++] = G[u][i].to;
dfs(G[u][i].to);
} bool check(int u) {
//cout<<G[u][0].vis<<endl;
if (gao[u] == G[u].size())return false;
return true;
} void Fluery(int s) {
st[all++] = s;
while (all) {
int now = st[all - ];
if (check(now))dfs(now);
else {
//cout<<rHash(now)<<endl;
road[tot++] = now;
all--;
}
}
} bool vis[MAX_N][MAX_N];
int newRoad[MAX_N]; int main() {
freopen("achromatic.in","r",stdin);
freopen("achromatic.out","w",stdout);
scanf("%d", &n);
for (k = ; ; k++) {
int t;
if (k & )t = k * (k - ) / ;
else t = k * k / ;
if (t > n)break;
}
k--;
if ((k & ) && n == (k * (k - )) / + )k--;
printf("%d\n", k);
for (int i = ; i < k; i++)
for (int j = ; j <= k / ; j++) {
int u = i;
int v = (i + j) % k;
G[u].push_back(edge(v));
}
Fluery();
int pos = ;
for (int i = ; i < tot - ; i++) {
int u = i, v = (i + ) % (tot - );
if (vis[u][v]) {
pos = u;
break;
}
vis[u][v] = vis[v][u] = ;
}
int nt = ;
for (int i = pos + ; i < tot - ; i++)
newRoad[nt++] = road[i];
for (int i = ; i <= pos; i++)newRoad[nt++] = road[i];
for (int i = ; i < tot - ; i++)
printf("%d ", newRoad[i] + );
if (n == tot - ) { return ; }
if (n - (tot - ) == ) {
int j = ;
while (j == newRoad[tot - ] + || j == newRoad[] + ) {
j++;
if (j == k + )j = ;
}
printf("%d\n", j);
return ;
}
printf("%d ", newRoad[] + );
int p = newRoad[] + ;
for (int i = tot; i < n; i++) {
int j = ;
while (j == p || (i == n - && j == newRoad[] + )) {
j++;
if (j == k + )j = ;
}
printf("%d ", j);
p = j;
}
printf("\n");
return ;
}
Codeforces Gym 100431A Achromatic Number 欧拉回路的更多相关文章
- Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】
2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...
- Codeforces Gym 101252D&&floyd判圈算法学习笔记
一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...
- Codeforces Gym 101190M Mole Tunnels - 费用流
题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...
- Codeforces Gym 101623A - 动态规划
题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...
- 【Codeforces Gym 100725K】Key Insertion
Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...
- codeforces gym 100553I
codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...
- CodeForces Gym 100213F Counterfeit Money
CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...
- Codeforces GYM 100876 J - Buying roads 题解
Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...
- codeforces Gym 100187J J. Deck Shuffling dfs
J. Deck Shuffling Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...
随机推荐
- Python中类的声明,使用,属性,实例属性,计算属性及继承,重写
Python中的类的定义以及使用: 类的定义: 定义类 在Python中,类的定义使用class关键字来实现 语法如下: class className: "类的注释" 类的实体 ...
- 如何封装RESTful Web Service
所谓Web Service是一个平台独立的,低耦合的,自包含的.可编程的Web应用程序,有了Web Service异构系统之间就可以通过XML或JSON来交换数据,这样就可以用于开发分布式的互操作的应 ...
- spring事务(Transaction )报 marked as rollback-only异常的原因及解决方法
很多朋友在使用spring+hibernate或mybatis等框架时经常遇到报Transaction rolled back because it has been marked as rollba ...
- OpenStack, kvm, qemu-kvm以及libvirt之关系
OpenStack, kvm, qemu-kvm以及libvirt之关系: KVM是最底层的hypervisor,它是用来模拟CPU的运行,它缺少了对network和周边I/O的支持,所以我们是没法直 ...
- Linuxx学习-特殊文件与进程
具有 SUID/SGID 权限的指令执行状态 SUID 的权限其实与进程的相关性非常的大!为什么呢?先来看看 SUID 的程序是如何被一般用户 执行,且具有什么特色呢? SUID 权限仅对二进制程序( ...
- HDU 5371 Manacher Hotaru's problem
求出一个连续子序列,这个子序列由三部分ABC构成,其中AB是回文串,A和C相同,也就是BC也是回文串. 求这样一个最长的子序列. Manacher算法是在所有两个相邻数字之间插入一个特殊的数字,比如- ...
- 蓝桥杯Java输入输出相关
转载自:http://blog.csdn.net/Chen_Tongsheng/article/details/53354169 一.注意点 1. 类名称必须采用public class Main方式 ...
- 【Java学习笔记之九】java二维数组及其多维数组的内存应用拓展延伸
多维数组声明 数据类型[][] 数组名称; 数据类型[] 数组名称[]; 数据类型数组名称[][]; 以上三种语法在声明二维数组时的功能是等价的.同理,声明三维数组时需要三对中括号,中括号的位置可以在 ...
- bootstrap3兼容ie8浏览器
bootstrap3 兼容IE8浏览器 2016-01-22 14:01 442人阅读 评论(0) 收藏 举报 分类: html5(18) 目录(?)[+] 近期在使用bootstrap这 ...
- python风格之包导入
导入总应该放在文件顶部, 位于模块注释和文档字符串之后, 模块全局变量和常量之前. 导入应该按照从最通用到最不通用的顺序分组: 标准库导入 第三方库导入 应用程序指定导入 每种分组中, 应该根据每个模 ...