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的更多相关文章

  1. CF 453C. Little Pony and Summer Sun Celebration

    CF 453C. Little Pony and Summer Sun Celebration 构造题. 题目大意,给定一个无向图,每个点必须被指定的奇数或者偶数次,求一条满足条件的路径(长度不超\( ...

  2. Codeforces 454E. Little Pony and Summer Sun Celebration

    题意:给n个点m条边的无向图,并给出每个点的访问次数奇偶,求构造一条满足条件的路径(点和边都可以走). 解法:这道题还蛮有意思的.首先我们可以发现在一棵树上每个儿子的访问次数的奇偶是可以被它的父亲控制 ...

  3. CF453C Little Pony and Summer Sun Celebration (DFS)

    http://codeforces.com/contest/456  CF454E Codeforces Round #259 (Div. 1) C Codeforces Round #259 (Di ...

  4. CF453C Little Pony and Summer Sun Celebration(构造、贪心(?))

    CF453C Little Pony and Summer Sun Celebration 题解 这道题要求输出任意解,并且路径长度不超过4n就行,所以给了我们乱搞构造的机会. 我这里给出一种构造思路 ...

  5. codeforces 454 E. Little Pony and Summer Sun Celebration(构造+思维)

    题目链接:http://codeforces.com/contest/454/problem/E 题意:给出n个点和m条边,要求每一个点要走指定的奇数次或者是偶数次. 构造出一种走法. 题解:可能一开 ...

  6. CF453C Little Pony and Summer Sun Celebration

    如果一个点需要经过奇数次我们就称其为奇点,偶数次称其为偶点. 考虑不合法的情况,有任意两个奇点不连通(自己想想为什么). 那么需要处理的部分就是包含奇点的唯一一个连通块.先随意撸出一棵生成树,然后正常 ...

  7. CF453C-Little Pony and Summer Sun Celebration【构造】

    正题 题目链接:https://www.luogu.com.cn/problem/CF453C 题目大意 \(n\)个点\(m\)条边的一张无向图,每个节点有一个\(w_i\)表示该点需要经过奇数/偶 ...

  8. [CF453C] Little Poney and Summer Sun Celebration (思维)

    [CF453C] Little Poney and Summer Sun Celebration (思维) 题面 给出一张N个点M条边的无向图,有些点要求经过奇数次,有些点要求经过偶数次,要求寻找一条 ...

  9. CodeForces 454C Little Pony and Expected Maximum

    Little Pony and Expected Maximum Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I6 ...

随机推荐

  1. Linux笔记-Linux命令初解2

    在看linux过程中,文件属性管理是一个难点,因而作为初学者的我来说,我直接将其放在后面来慢慢研究,因而我个人觉得先学习后面一些知识点之后,回过头来将一些你所不懂的去解透,这是极好的意见事情.对了,我 ...

  2. bug:执行到数据库连接后停止运行,而且不报错的奇怪情况----可能是多方同时访问造成的

    数据库运行过程中奇怪停止. 即执行到“database connected ”停止运行,而且不产生任何报错信息 程序反复检查没有问题,折腾半天解决了: 可能是多个客户端操作同一个表格,多方同时操作造成 ...

  3. XML的基本概念和Android下的使用

    1. XML的基本概念 1. 什么是XML: 1). XML是指可扩展标记语言(eXtensible Markup Language),它是一种标记语言,很类似HTML.它被设计的宗旨是表示数据,而非 ...

  4. jquery 选择唯一值 选择器“”非“用法

    $(document).ready(function () { $("#addwork").hide(); $(".xi").click(function(){ ...

  5. 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波

    原文:http://blog.csdn.net/xiaowei_cqu/article/details/7785365 邻域滤波(卷积)   邻域算子值利用给定像素周围像素的值决定此像素的最终输出.如 ...

  6. unity 和 iOS/Android 信息交互(方法调用)

    参考文章均来源于[大神雨松momo]的文章. unity -> iOS // unity 程序 usingSystem.Runtime.InteropServices; usingUnityEn ...

  7. Linq lambda 匿名方法

    课程6 委托.匿名方法.Lambda表达式.Linq查询表达式 上课日志1 一.委托的基本认识 提问:能不能把方法作为参数传递??? 也即是能不能声明一个能存放方法的变量呢——委托. 委托是一种数据类 ...

  8. 几个常用的内存、CPU飙高 分析工具

    Process Hacker.Windbg.vs2017 调试托管内存.Microsoft.Samples.Debugging.ants memory profiler.ants performanc ...

  9. Spring中三个重要概念 IOC AOP Bean

    Spring中三个重要概念 IOC AOP Bean 首先讲解一下Spring框架,以及为什么要使用Spring 框架? spring 是一个很好的容器框架, 是轻量级的IoC和AOP的容器框架,主要 ...

  10. Cookie写入之path的坑

    问题 我在/page/index/index.html中向浏览器添加了一个useid的cookie(这里没有指定path), 然后试着从/page/demo/demo.html中取值,发现无法取到, ...