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 ...
随机推荐
- FocusBI:地产分析&雪花模型
微信公众号:FocusBI关注可了解更多的商业智能.数据仓库.数据库开发.爬虫知识及沪深股市数据推送.问题或建议,请关注公众号发送消息留言;如果你觉得FocusBI对你有帮助,欢迎转发朋友圈或在文章末 ...
- HighChart 体验之旅 (后台传递JSON参数和数据的方法)
转自:http://www.cnblogs.com/daviddai/archive/2013/04/12/Highchart.html 官网:http://www.highcharts.com/ 中 ...
- echo(),print(),print_r()之间的区别?
echo是PHP语句, print和print_r是函数,语句没有返回值,函数可以有返回值(即便没有用) print只能打印出简单类型变量的值(如int,string) print_r可以打印出复 ...
- nodejs学习笔记三(用户注册、登录)
1.定接口 /user 接口 输入 act=reg&user=aaa&pass=123456 输出 {& ...
- 使用javascript获取wx.config内部字段解决微信分享
背景 在微信分享开发的时候我们通常的流程是 <?php require_once "jssdk.php"; $jssdk = new JSSDK("yourAppI ...
- Bundle传递数据,Handler更新UI
Bundle主要用于传递数据:它保存的数据,是以key-value(键值对)的形式存在的. Bundle经常使用在Activity之间或者线程间传递数据,传递的数据可以是boolean.byte.in ...
- 十九、异步任务编排CompletableFuture
一.简介 并发编程中我们经常创建异步线程来执行任务.但是,当异步任务之间存在依赖关系时,使得我们开发过程变得更加复杂.比如: 1.线程2依赖于线程1的执行结果 2.线程3依赖于线程1和线程2执行结果的 ...
- Shiro官方快速入门10min例子源码解析框架2-Session
Shiro自身维护了一套session管理组件,它可以独立使用,并不单纯依赖WEB/Servlet/EJB容器等环境,使得它的session可以任何应用中使用. 2-Session)主要介绍在quic ...
- 实习小结(三)--- 权限管理(RBAC)
这一周,大多数时间 用来做需求分析,细化每个页面需要实现的功能.由于这个项目需要四种身份登录查看,分别是学生,老师,领导,管理员.每个身份登入系统显示得页面都不相同,四个角色分析完成后,统计了一下页面 ...
- Python Django 路由分发
mysite1 为一个django工程 cmdb为一个项目 dashboard为一个项目 在mysite1工程下的urls.py中定义如下: from django.conf.urls import ...