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 ...
随机推荐
- Yii2.0学习--目录结构
目录结构: 创建一个控制器: <?php /** * Created by Haima. * Author:Haima * QQ:228654416 * Date: 2018/8/23 * Ti ...
- Python基础-os模块 sys模块
sys模块 与操作系统交互的一个接口 文件夹相关 os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') ...
- Shuffle UVA - 12174 尺取法
题目:题目链接 思路:见紫书,对具体操作方式还不是很理解,代码是从一个题解里看的,以后多回顾下,需要理解 代码: #include <iostream> #include <cstr ...
- while True 死循环
while True 死循环示例: count = 0 #给count设置变量为0 while True: count += 1 #每循环一次,count+1 : count += 1 等同于coun ...
- matlab callback 数据传递
M文件中内的每个Callback都可以视为一个独立的可执行的接口,因此,任一个Callback触发后所执行的运算值若要在其他Callback中使用,就无法与MATLAB工作空间内的变量继续执行操作,也 ...
- C++异常安全的赋值运算符重载 【微软面试100题 第五十五题】
题目要求: 类CMyString的声明如下: class CMyString { public: CMyString(char *pData=NULL); CMyString(const CMyStr ...
- Flash中国地图 开放源码
Flash中国地图,以Object为数据源,便于实现基于中国地图的可视化项目. 特征: swc,便于导入到Flex项目中 数据源为Object,比XML更方便 数据驱动的地图块颜色和Hover颜色 可 ...
- dubbo Protocol实现剖析
title: dubbo Protocol实现剖析 date: 2018-09-09 19:10:07 tags: --- 2.6.3版本,之前读的是2.4.9版本 本篇主要阐述dubbo rpc的c ...
- csrf 攻击及防御
1.什么是CSRF攻击: CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:C ...
- 设计模式(四)建造者模式 Builder
Builder: <Effective Java> 第2条:遇到多个构造器参数时要考虑用构建器. 建造者模式(Builder Pattern),也称生成器模式,定义如下: 将一个复杂对象的 ...