题面

题解

神仙构造题。

分五种情况考虑:

  • 如果存在一个环,那么令环上的点权值为\(1\),其余点权值为\(0\)。
  • 如果存在一个度数大于\(3\)的点,令这个点的权值为\(2\),和它相邻的点权值为\(1\),否则权值为\(0\)。
  • 如果存在两个度数等于\(3\)的点,令这两个点的路径上点的权值为\(2\),其余的点权值为\(1\)。
  • 如果只有一个点度数为\(3\),那么这张图一定是这个点伸出三条链,设三条链的长度分别为\(l_1, l_2, l_3\),那么有解当且仅当\(\frac 1{l_1 + 1} + \frac 1{l_2 + 1} + \frac 1{l_3 + 1} \leq 1\)。
  • 如果没有点度数为\(3\),可以证明一定无解。

于是就可以按照结论欢乐构造了。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout) inline int read()
{
int data = 0, w = 1; char ch = getchar();
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
} const int maxn(1e5 + 10);
struct edge { int next, to; } e[maxn << 1];
int head[maxn], e_num, n, m, vis[maxn], d[maxn], deg[maxn];
std::vector<int> vec[3];
inline void add_edge(int from, int to)
{
e[++e_num] = (edge) {head[from], to};
head[from] = e_num, ++deg[to];
} void Set(int x)
{
vis[x] = 0; if (!d[x]) d[x] = 1;
for (int i = head[x]; i; i = e[i].next)
if (vis[e[i].to]) Set(e[i].to);
} int findCir(int x, int f)
{
vis[x] = 1;
for (int i = head[x]; i; i = e[i].next)
if (!vis[e[i].to]) { if (findCir(e[i].to, x)) return 1; }
else if (e[i].to != f) return 1;
return 0;
} int findDeg(int x, int f)
{
if (f && deg[x] == 3) return d[x] = 2, 1;
for (int i = head[x]; i; i = e[i].next)
if (e[i].to != f) if (findDeg(e[i].to, x)) { d[x] = 2; return 1; }
return 0;
} void dfs(int x, int f, std::vector<int> &v)
{
v.push_back(x);
for (int i = head[x]; i; i = e[i].next)
if (e[i].to != f) dfs(e[i].to, x, v);
} int main()
{
for (int T = read(); T--; )
{
n = read(), m = read();
memset(head, 0, (n + 1) << 2), memset(vis, 0, (n + 1) << 2);
memset(d, 0, (n + 1) << 2), memset(deg, 0, (n + 1) << 2), e_num = 0;
for (int i = 1, a, b; i <= m; i++)
a = read(), b = read(), add_edge(a, b), add_edge(b, a);
int f = 0;
for (int i = 1; !f && i <= n; i++)
if (!vis[i]) if ((f = findCir(i, 0))) Set(i);
for (int i = 1; !f && i <= n; i++)
if (deg[i] > 3) { d[i] = 2, Set(i), f = 1; }
for (int i = 1; !f && i <= n; i++)
if (deg[i] == 3) if ((f = findDeg(i, 0)))
memset(vis, 1, sizeof vis), Set(i);
for (int i = 1; !f && i <= n; i++) if (deg[i] == 3)
{
int cur = 0; vec[0].clear(), vec[1].clear(), vec[2].clear();
for (int j = head[i]; j; j = e[j].next) dfs(e[j].to, i, vec[cur++]);
if (vec[0].size() > vec[1].size()) std::swap(vec[0], vec[1]);
if (vec[0].size() > vec[2].size()) std::swap(vec[0], vec[2]);
if (vec[1].size() > vec[2].size()) std::swap(vec[1], vec[2]);
if (vec[1].size() == 1 || (vec[0].size() == 1 && vec[1].size() == 2
&& vec[2].size() < 5)) continue;
f = 1;
if (vec[2].size() >= 5)
{
d[i] = 6, d[vec[0][0]] = 3, d[vec[1][0]] = 4, d[vec[1][1]] = 2;
for (int j = 0; j < 5; j++) d[vec[2][j]] = 5 - j;
}
else
{
d[i] = (vec[0].size() + 1) * (vec[1].size() + 1) * (vec[2].size() + 1);
for (int j = 0; j < 3; j++) for (int k = 0; k < (int) vec[j].size(); k++)
d[vec[j][k]] = d[i] / (vec[j].size() + 1) * (vec[j].size() - k);
}
}
if (!f) { puts("NO"); continue; } puts("YES");
for (int i = 1; i <= n; i++) printf("%d%c", d[i], " \n"[i == n]);
}
return 0;
}

CF830E Perpetual Motion Machine的更多相关文章

  1. Thinking Clearly about Performance

    http://queue.acm.org/detail.cfm?id=1854041 The July/August issue of acmqueue is out now acmqueue is ...

  2. unity5之代码创建状态机,玩的666

    http://blog.csdn.net/litaog00/article/details/50483189 最近做项目的时候用到了状态机,网上搜了一下帖子,大部分都是简单介绍使用方法的,讲解的详细的 ...

  3. Machine and Deep Learning with Python

    Machine and Deep Learning with Python Education Tutorials and courses Supervised learning superstiti ...

  4. Motion control encoder extrapolation

    Flying Saw debug Part1 Encoder extrapolation Machine introduction A tube cutting saw, is working for ...

  5. booklist for machine learning

    Recommended Books Here is a list of books which I have read and feel it is worth recommending to fri ...

  6. [C5] Andrew Ng - Structuring Machine Learning Projects

    About this Course You will learn how to build a successful machine learning project. If you aspire t ...

  7. Pattern Recognition and Machine Learning-02-1.0-Introduction

    Introduction The problem of searching for patterns in data is a fundamental one and has a long and s ...

  8. New Machine Learning Server for Deep Learning in Nuke(翻译)

    最近一直在开发Orchestra Pipeline System,歇两天翻译点文章换换气.这篇文章是无意间看到的,自己从2015年就开始关注机器学习在视效领域的应用了,也曾利用碎片时间做过一些算法移植 ...

  9. 【Machine Learning】KNN算法虹膜图片识别

    K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

随机推荐

  1. MongoDB和Java(2):普通用户启动mongod进程

    最近花了一些时间学习了下MongoDB数据库,感觉还是比较全面系统的,涉及了软件安装.客户端操作.安全认证.副本集和分布式集群搭建,以及使用Spring Data连接MongoDB进行数据操作,收获很 ...

  2. A Deep Dive Into Draggable and DragTarget in Flutter

    https://medium.com/flutter-community/a-deep-dive-into-draggable-and-dragtarget-in-flutter-487919f6f1 ...

  3. 【转载】C#中List集合中Last和LastOrDefault方法的差别

    在C#的List集合操作中,Last方法和LastOrDefault方法都会用来查找集合中最后一个符合条件的元素对象,但Last和LastOrDefault方法还是有差别的,建议使用LastOrDef ...

  4. JavaWeb 之 Filter 验证用户登录案例

    需求: 1. 访问一个网站的资源.验证其是否登录 2. 如果登录了,则直接放行. 3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录". 代码实现: import j ...

  5. Java文件流下载并提示文件不存在

    做文件下载功能的时候,一般使用流的形式下载文件, 如果源文件不存在,下载页面可能就会没有提示,或者一片空白 用户操作之后可能一头雾水,那如何友好提示呢? 想到的有两种 1.可以尝试下载一个名称为:文件 ...

  6. Jupyter Notebook修改默认的工作目录

    Jupyter Notebook修改默认的工作目录 方法1:通过配置文件修改 只适合从命令行启动notebook生成配置文件,如果你已经在windows环境变量中设置好了jupyter noteboo ...

  7. 树莓派配置wifi网络+更换镜像源

    刚安装完系统后,采用的是树莓派通过网线连接笔记本wifi共享方式联网,后面考虑不使用网线,让树莓派使用wifi联网. 一.配置无线网络 1.通过ssh登录树莓派,输入用户名和密码后,输入如下命令进入图 ...

  8. 利用ViewStub实现布局懒惰加载

    这个问题也是头条面试官问的,本身没什么难度,但以前确实没仔细研究过. 1.使用介绍 ViewStub是一种不可见的尺寸为0的View,用来实现布局资源的懒加载.当ViewStub被设置为用户可见或其  ...

  9. X509IncludeOption 枚举

    X509IncludeOption 枚举 指定 X.509 数据应包括 X.509 证书链的哪些内容. EndCertOnly 2 X.509 链信息中仅包括最终证书. ExcludeRoot 1 包 ...

  10. spring cloud (五) 熔断面板 聚合熔断 turbine

    改造feign 项目 1 启动类添加注解  @EnableHystrix 2 添加如下配置文件 #ji eureka.instance.metadata-map.cluster=MAIN#actuat ...