原题链接: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 欧拉回路的更多相关文章

  1. 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 ...

  2. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  3. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  4. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  5. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

  6. codeforces gym 100553I

    codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...

  7. CodeForces Gym 100213F Counterfeit Money

    CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...

  8. Codeforces GYM 100876 J - Buying roads 题解

    Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...

  9. codeforces Gym 100187J J. Deck Shuffling dfs

    J. Deck Shuffling Time Limit: 2   Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...

随机推荐

  1. Python基础——列表(list)

    创建列表(list) 通过[]来创建list结构,里面放任何类型都可以,没有长度限制. list1=[] type(list1) list1=[1,2,3,4] list1 list1=['] lis ...

  2. 补之前 如何改变jupyter打开文件的路径

    目录 如何改变jupyter打开文件的路径 第一种方法: 第二种方法 第三种方法 如何改变jupyter打开文件的路径 当我们直接打开jupyter时,直接加载的是我们的C盘文件 现在我们想打开其他盘 ...

  3. 设置eclipse中的${user}

    打开eclipse根目录找到eclipse.ini文件增加初始配置: -Duser.name=snzigod@hotmail.com 重启eclipse后${user}变量的值就变成了snzigod@ ...

  4. luogu1208 尼克的任务

    倒着推就是了 #include <iostream> #include <cstdio> #include <vector> using namespace std ...

  5. Flask_WTForms源码流程(糙版)

    from flask import Flask, render_template, request, redirect # Form# _fields# validate# validata_name ...

  6. PHP协程是通过生成器实现的,这里测试了PHP生成器的一些特性

    学习PHP的生成器,测试了一些特性.代码如下: function gen() { $name = (yield 'hello'); $nickname = (yield 'world'); yield ...

  7. Model View Controller(MVC) in PHP

    The model view controller pattern is the most used pattern for today’s world web applications. It ha ...

  8. JDBC 学习笔记(三)—— JDBC 常用接口和类,JDBC 编程步骤

    1. JDBC 常用接口和类 DriverManager 负责管理 JDBC 驱动的服务类,程序中主要的功能是获取连接数据库的 Connection 对象. Connection 代表一个数据库连接对 ...

  9. 开发者选择短视频SDK,为何青睐七牛云?

    从文字到图片再到视频的互联网内容媒介发展途径,随着 5g 技术的逐渐落地愈发清晰.短视频市场中的角力也随着诸多资本和创业者的涌入,进入到白热化阶段.这样的情况下,选择合适的短视频SDK产品就显得尤为重 ...

  10. CSS编码规范(转)

    1 前言 CSS作为网页样式的描述语言,在百度一直有着广泛的应用.本文档的目标是使CSS代码风格保持一致,容易被理解和被维护. 虽然本文档是针对CSS设计的,但是在使用各种CSS的预编译器(如less ...