codeforces 453C Little Pony and Summer Sun Celebration
codeforces 453C Little Pony and Summer Sun Celebration
这道题很有意思,虽然网上题解很多了,但是我还是想存档一下我的理解。
题意可以这样转换:初始所有点有 \(01\) 状态,每经过一次状态就翻转,求一条路径使得最后状态全 \(1\)。
以某个状态 \(1\) 的点开始,搜出它的dfs序。dfs序的长度必定是 \(2n-1\)(因为dfs树有 \(n-1\) 条边,每条边遍历两次)。我们把这个dfs序列存在数组 \(res[0..2n-2]\) 中。当遍历到 \(res[i]\) 时,如果 \(res[i-1]\) 的状态是 \(1\),并且以后不会再遍历到 \(res[i-1]\),那么我们可以在原序列(\(...->res[i-1]->res[i]->...\))的基础上再加上 \(->res[i-1]->res[i]->\)(新序列 \(...->res[i-1]->res[i]->\)res[i-1]->res[i]\(->...\))。最后如果 \(res[2n-2]\) 状态是 \(1\),从序列中删除即可。
基于这种构造方法,最后序列的长度范围在 \([2n-1, 4n-1]\)。(比dfs序列最多多 \(2n\) 个)
以下代码有两种实现方式,一种是先把dfs序搜出来再做,一种是dfs过程中直接求出最终序列。
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(x) (int)x.size()
#define de(x) cout<< #x<<" = "<<x<<endl
#define dd(x) cout<< #x<<" = "<<x<<" "
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N=101010;
int n,m;
int a[N];
vi res, ans;
vi g[N];
bool vis[N], la[N<<1];
void dfs(int u,int fa) {
res.pb(u);
vis[u]=1;
rep(i,0,sz(g[u])) {
int v=g[u][i];
if(v==fa||vis[v]) continue;
dfs(v, u);
res.pb(u);
}
}
inline void upd(int u) {
ans.pb(u);
a[u]^=1;
}
inline void print() {
rep(i,1,n+1) if(a[i]) {
puts("-1");
return ;
}
printf("%d\n",sz(ans));
rep(i,0,sz(ans)) printf("%d%c",ans[i]," \n"[i==sz(ans)-1]);
}
int main() {
while(~scanf("%d%d",&n,&m)) {
///init
rep(i,0,n+1) g[i].clear();
res.clear();
ans.clear();
memset(la,0,sizeof(la));
///read
rep(i,0,m) {
int u,v;scanf("%d%d",&u,&v);
g[u].pb(v);
g[v].pb(u);
}
rep(i,1,n+1) scanf("%d",a+i);
///solve
memset(vis,0,sizeof(vis));
rep(i,1,n+1) if(a[i]) {
dfs(i, i);
break;
}
memset(vis,0,sizeof(vis));
for(int i=sz(res)-1;~i;--i) if(!vis[res[i]]) {
vis[res[i]]=1;
la[i]=1;
}
rep(i,0,sz(res)) {
int u=res[i];
upd(u);
if(i&&a[res[i-1]]&&la[i-1]) {
upd(res[i-1]);
upd(u);
}
}
if(sz(ans)&&a[ans[sz(ans)-1]]) a[ans[sz(ans)-1]]=0, ans.pop_back();
print();
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(x) (int)x.size()
#define de(x) cout<< #x<<" = "<<x<<endl
#define dd(x) cout<< #x<<" = "<<x<<" "
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N=101010;
int n,m;
int a[N];
vi ans;
vi g[N];
bool vis[N], la[N<<1];
inline void upd(int u) {
ans.pb(u);
a[u]^=1;
}
void dfs(int u,int fa) {
upd(u);
vis[u]=1;
rep(i,0,sz(g[u])) {
int v=g[u][i];
if(v==fa||vis[v]) continue;
dfs(v, u);
upd(u);
if(a[v]) {
upd(v);
upd(u);
}
}
}
inline void print() {
rep(i,1,n+1) if(a[i]) {
puts("-1");
return ;
}
printf("%d\n",sz(ans));
rep(i,0,sz(ans)) printf("%d%c",ans[i]," \n"[i==sz(ans)-1]);
}
int main() {
while(~scanf("%d%d",&n,&m)) {
///init
rep(i,0,n+1) g[i].clear();
ans.clear();
memset(la,0,sizeof(la));
memset(vis,0,sizeof(vis));
///read
rep(i,0,m) {
int u,v;scanf("%d%d",&u,&v);
g[u].pb(v);
g[v].pb(u);
}
rep(i,1,n+1) scanf("%d",a+i);
///solve
rep(i,1,n+1) if(a[i]) {
dfs(i, i);
break;
}
if(sz(ans)&&a[ans[sz(ans)-1]]) a[ans[sz(ans)-1]]=0, ans.pop_back();
print();
}
return 0;
}
codeforces 453C Little Pony and Summer Sun Celebration的更多相关文章
- CF 453C. Little Pony and Summer Sun Celebration
CF 453C. Little Pony and Summer Sun Celebration 构造题. 题目大意,给定一个无向图,每个点必须被指定的奇数或者偶数次,求一条满足条件的路径(长度不超\( ...
- Codeforces 454E. Little Pony and Summer Sun Celebration
题意:给n个点m条边的无向图,并给出每个点的访问次数奇偶,求构造一条满足条件的路径(点和边都可以走). 解法:这道题还蛮有意思的.首先我们可以发现在一棵树上每个儿子的访问次数的奇偶是可以被它的父亲控制 ...
- CF453C Little Pony and Summer Sun Celebration (DFS)
http://codeforces.com/contest/456 CF454E Codeforces Round #259 (Div. 1) C Codeforces Round #259 (Di ...
- CF453C Little Pony and Summer Sun Celebration(构造、贪心(?))
CF453C Little Pony and Summer Sun Celebration 题解 这道题要求输出任意解,并且路径长度不超过4n就行,所以给了我们乱搞构造的机会. 我这里给出一种构造思路 ...
- codeforces 454 E. Little Pony and Summer Sun Celebration(构造+思维)
题目链接:http://codeforces.com/contest/454/problem/E 题意:给出n个点和m条边,要求每一个点要走指定的奇数次或者是偶数次. 构造出一种走法. 题解:可能一开 ...
- CF453C Little Pony and Summer Sun Celebration
如果一个点需要经过奇数次我们就称其为奇点,偶数次称其为偶点. 考虑不合法的情况,有任意两个奇点不连通(自己想想为什么). 那么需要处理的部分就是包含奇点的唯一一个连通块.先随意撸出一棵生成树,然后正常 ...
- CF453C-Little Pony and Summer Sun Celebration【构造】
正题 题目链接:https://www.luogu.com.cn/problem/CF453C 题目大意 \(n\)个点\(m\)条边的一张无向图,每个节点有一个\(w_i\)表示该点需要经过奇数/偶 ...
- [CF453C] Little Poney and Summer Sun Celebration (思维)
[CF453C] Little Poney and Summer Sun Celebration (思维) 题面 给出一张N个点M条边的无向图,有些点要求经过奇数次,有些点要求经过偶数次,要求寻找一条 ...
- CodeForces 454C Little Pony and Expected Maximum
Little Pony and Expected Maximum Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I6 ...
随机推荐
- SQL Serever学习11——数据库的安全管理
公司管理软件设计完成,但是日常工作繁忙,向领导提出增加几个管理员,帮助管理和维护系统,领导同意了,但是要求一定要管理好这几个管理员用户,保证数据库的安全. 修改身份验证模式 数据库验证机制 sqlse ...
- C#中的分部类和分部方法:partial
这篇文章主要介绍了C#中的分部类和分部方法,讲解了类的拆分和方法的定义的拆分,需要的朋友可以参考下可以将类或结构.接口或方法的定义拆分到两个或多个源文件中.每个源文件包含类型或方法定义的一部分,编译应 ...
- Docker学习(三): Dockerfile指令介绍
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...
- 撩课-Java每天5道面试题第10天
撩课Java+系统架构 视频 点击开始学习 81.Servlet的会话机制? HTTP 是一种无状态协议, 这意味着每次客户端检索网页时, 都要单独打开一个服务器连接, 因此服务器不会记录下 先前客户 ...
- JAVA基础之——使用idea创建maven项目 以及使用tomcat本地调试springmvc
前言:关于这个话题网上有很多,本文旨在引导实战纠偏,理论偏少,如果按照步骤还不能达到本文目的,请留言. 1 环境准备 1.1 软件准备 idea:官方下载社区版,下载后安装 maven:Apache- ...
- hdu 1075 What Are You Talking About 字典树模板
What Are You Talking About Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/204800 K ...
- dubbo客户端源码分析(一)
rpc框架有很多,公司自研.开源的thrift.dubbo.grpc等.我用过几个框架,了解了一下实现原理,客户端基本都是用代理实现,jdk动态代理.cglib等.最近一段时间想了解一下dubbo源码 ...
- docker 卸载
1首先搜索已经安装的docker 安装包 [root@localhost ~]# yum list installed|grep docker 或者使用该命令 [root@localhost ~]# ...
- 工作经验:mybatis 处理 oracle Long 类型
前言:mybatis 接收 oracle 中 LONG 类型的,报错:无效的列类型: getCLOB not implemented for class oracle.jdbc.driver.T4CL ...
- 使用jQuery的validation插件实现表单校验
前端表单校验: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...