zoukankan      html  css  js  c++  java
  • 【CF453C】Little Pony and Summer Sun Celebration

    题目

    题目链接:https://codeforces.com/problemset/problem/453/C
    给一个无向图,n个点m条边,给定一个01序列,如果a[i]=1,要求走到这个点奇数次,否则,要求走到这个点偶数次,请你任选起点,输出满足要求的经过点的序列和序列长度,序列长度不能超过4n。
    (n,mleq 10^5)

    思路

    如果有多张连通图且至少有两张连通图中都有要求经过次数为奇数的点显然无解。
    否则必然有解。
    我们把经过次数为奇数定义为黑色,经过次数为偶数为白色。我们的目标是把所有节点全部变为白色。
    随便找一棵生成树,按照 dfs 序染色。假设 (x) 的子树内所有点都已经变为白色了,那么返回 (x) 父亲 (y) 的时候,判断如果 (x) 是黑色,就再次经过 (y o x o y) 这两条边把 (x,y) 反色。
    这样最终根节点肯能是黑色或者白色,如果是黑色,那么我们最后回到根节点的一步就不走就行了。
    时间复杂度 (O(n+m))。不考虑 (x o y o x) 的路径的话,一个节点 (x) 会被经过的次数是其儿子数量 (+1),然后 (x o y o x) 的路径最多只会走 (m) 次,所以路径长度上界是 (sum_{xin T} ext{deg}_x+2mleq 4n)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100010;
    int n,m,tot,head[N],father[N],col[N];
    bool flag,vis[N],vis2[N];
    stack<int> st;
    
    struct edge
    {
    	int next,to;
    }e[N*2];
    
    void add(int from,int to)
    {
    	e[++tot]=(edge){head[from],to};
    	head[from]=tot;
    }
    
    bool dfs1(int x,int fa)
    {
    	if (col[x]) return 1;
    	if (vis2[x]) return 0;
    	vis2[x]=1;
    	for (int i=head[x];~i;i=e[i].next)
    		if (e[i].to!=fa) dfs1(e[i].to,x);
    	return 0;
    }
    
    void dfs2(int x,int fa)
    {
    	st.push(x);
    	vis[x]=1; col[x]^=1;
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (v!=fa && !vis[v])
    		{
    			dfs2(v,x);
    			st.push(x); col[x]^=1;
    			if (col[v])
    			{
    				st.push(v); st.push(x);
    				col[v]^=1; col[x]^=1;
    			}
    		}
    	}
    }
    
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	for (int i=1,x,y;i<=m;i++)
    	{
    		scanf("%d%d",&x,&y);
    		add(x,y); add(y,x);
    	}
    	for (int i=1;i<=n;i++)
    		scanf("%d",&col[i]);
    	for (int i=1;i<=n;i++)
    		if (!vis[i])
    		{
    			int s=dfs1(i,0);
    			if (flag && s) return printf("-1"),0;
    			flag|=s;
    			if (s) dfs2(i,0);
    			if (col[i]) st.pop();
    		}
    	printf("%d
    ",st.size());
    	for (;st.size();st.pop()) printf("%d ",st.top());
    	return 0;
    }
    
  • 相关阅读:
    js关于页面坐标api
    js面向对象之创建对象
    Web前端安全问题
    js操作cookie
    css清除浮动
    块级格式化上下文(block formatting context)
    《python核心编程》笔记——系统限制
    《python核心编程》笔记——文件的创建、读取和显示
    黑客们的故事连载十二 “蠕虫来袭”:莫里斯
    黑客们的故事连载十一 下村努—虚拟战争追逐
  • 原文地址:https://www.cnblogs.com/stoorz/p/14454856.html
Copyright © 2011-2022 走看看