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. [PY3]——基本语法

    Python3基本语法-xmind图 常量/变量 1. 常量:一旦赋值就不可再改变.不能对它重新赋值.python不存在常量2. 字面常量:一个单独出现的量,未赋值给任何变量或常量3. 变量: i=3 ...

  2. xml布局中include的使用

    参考:http://blog.csdn.net/harvic880925/article/details/17263275 include_button1.xml <?xml version=& ...

  3. [转]emailjs-smtp-client

    本文转自:https://github.com/emailjs/emailjs-smtp-client/blob/master/README.md SMTP Client SMTP Client al ...

  4. [转].Net Windows服务安装完成后自动启动

    本文转自:http://www.cnblogs.com/hb_cattle/archive/2011/12/04/2275319.html 考虑到部署方便,我们一般都会将C#写的Windows服务制作 ...

  5. Git——新手入门与上传项目到远程仓库GitHub

    Git:先进的分布式版本控制系统,一个开源式的分布式版本控制工具. Git安装 在Windows操作系统下,访问Git下载地址https://git-for-windows.github.io/ 注册 ...

  6. table 中的tr 行点击 变换颜色背景

    <style> table{border-collapse: collapse;border-spacing: 0; width: 100%;} table tr th,td{border ...

  7. 激活 IntelliJ IDEA

    1.点击下面的链接下载 JetbrainsIdesCrack-4.2-release.jar 链接:https://pan.baidu.com/s/1eNY_bwxF7Efl4QG0yh6l1A  提 ...

  8. 时间格式转换成JUN.13,2017

    SimpleDateFormat sdf = new SimpleDateFormat("MMM.dd,yyyy", Locale.ENGLISH); String negotia ...

  9. 【9】log4net 实例

    一.创建项目并添加nuget: Install-Package log4net   二.添加配置文件 <configuration> <configSections> < ...

  10. Thymeleaf学习记录(6)--迭代及条件语法

    迭代: 条件选择: IF-THEN: (if) ? (then) IF-THEN-ELSE: (if) ? (then) : (else) 默认: (value) ?: (defaultvalue) ...