zoukankan      html  css  js  c++  java
  • 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
    ",sz(ans));
    	rep(i,0,sz(ans)) printf("%d%c",ans[i]," 
    "[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
    ",sz(ans));
    	rep(i,0,sz(ans)) printf("%d%c",ans[i]," 
    "[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;
    }
    
  • 相关阅读:
    leetcode 1. Two Sum
    leetcode 168. Excel Sheet Column Title
    [LeetCode] Water and Jug Problem 水罐问题
    leetcode 80 Remove Duplicates from Sorted Array II
    leetcode 239. Sliding Window Maximum
    文件处理
    python网络编程 之 twisted
    ICMP & ping & traceroute
    Java String 转整形
    Java 字符数字得到整数
  • 原文地址:https://www.cnblogs.com/wuyuanyuan/p/8675210.html
Copyright © 2011-2022 走看看