zoukankan      html  css  js  c++  java
  • CF 453C. Little Pony and Summer Sun Celebration

    CF 453C. Little Pony and Summer Sun Celebration

    构造题。

    题目大意,给定一个无向图,每个点必须被指定的奇数或者偶数次,求一条满足条件的路径(长度不超(4n)).没有输出-1

    首先我们应该判断掉-1的情况

    图不连通且所有的奇数点不在同一个联通块内

    发现只有上述情况可以

    为什么

    我们发现图不连通但所有的奇数点在同一个联通块内和图连通在本质上是一种情况.

    我们在这里就只考虑图连通该怎么办.

    首先,我们对于这张图求出他任意一个生成树
    之后我们进行dfs,在dfs再次回到(x)点时(即我们已经处理玩了(x)的所有子树),我们就要求他合法.但是,万一他不合法怎么办?

    很简单,我们就利用他的父亲.即(x->f->x)这样的话,虽然改变了(f),但是我们完成了将(x)的子树全部合法的任务

    其他的所有点都以此类推

    但是,万一我们求完整棵树,发现根不合法怎么办?

    不慌,我们先随便找到(root)的一个儿子,记为(s)

    那么直接(root->s-root->s)即可(注意我们此时在(root),结束在(s))

    发现(root)变了,但是(s)经过了两次,相当于没改变,由上可知,肯定合法.

    至于(4n)的限制

    我们发现每个点最多下1步,上1步,来回判不合法2步.但是有叶子的存在,答案是小于(4n)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<vector>
    using namespace std;
    const int N = 1e5 + 3;
    int tot = 1;
    int n,m;
    struct edhe{
        int to;
        int nxt;    
    }e[N << 1];
    int head[N];
    int s[N];
    bool vis[N];
    int now[N];
    int size,num1,root;
    vector <int> G[N];
    vector <int> ans;
    inline int read(){
        int v = 0,c = 1;char ch = getchar();
        while(!isdigit(ch)){
            if(ch == '-') c = -1;
            ch = getchar(); 
        }
        while(isdigit(ch)){
            v = v * 10 + ch - 48;
            ch = getchar(); 
        }
        return v * c;
    }
    inline void add(int x,int y){
        e[++tot].to = y;
        e[tot].nxt = head[x];
        head[x] = tot;  
    }
    inline void dfs(int x){
        vis[x] = 1;
        size++;num1 += (s[x] == 1);
        for(int i = head[x];i;i = e[i].nxt){
            int y = e[i].to;
            if(!vis[y]) {G[x].push_back(y);dfs(y);}
        }
    }
    inline void dfs2(int x,int f){
        ans.push_back(x);
        now[x] ^= 1;
        for(int i = 0;i < (int)G[x].size();++i){
            int y = G[x][i];
            dfs2(y,x); 
            ans.push_back(x);
            now[x] ^= 1;
        }
        if(now[x] != s[x] && x != root){
            ans.push_back(f);
            ans.push_back(x);
         //   ans.push_back(f);
         	now[x] ^= 1;
    	    now[f] ^= 1;
    	}
    	if(now[x] != s[x] && x == root){
    		ans.push_back(G[x][0]);
    		ans.push_back(root);
    		ans.push_back(G[x][0]);
    		now[x] ^= 1;
    	}
            return ;
    }
    int main(){
        n = read(),m = read();
        for(int i = 1;i <= m;++i){
            int x = read(),y = read();
            add(x,y);add(y,x);  
        }
        for(int i = 1;i <= n;++i) scanf("%d",&s[i]);
        int g = 0;
        for(int i = 1;i <= n;++i) if(s[i] == 1) g++;	
        if(g == 0){puts("0");return 0;}
        if(m == 0){
        	if(g != 1){puts("-1");return 0;}
    		else{
    			for(int i = 1;i <= n;++i) if(s[i] == 1) {printf("1
    %d
    ",i);return 0;}
    		}
        }
        for(int i = 1;i <= n;++i){
    		if(!vis[i]){
    			size = 0,num1 = 0;
    			dfs(i);
    			if(num1) root = i;
    		}
    	}
    	if(size != n && num1 != g){puts("-1");return 0;}
        dfs2(root,0);
        printf("%d
    ",ans.size());
        for(int i = 0;i < (int)ans.size();++i) printf("%d ",ans[i]);
        return 0;   
    }
    
  • 相关阅读:
    n个元素进栈,有几种出栈方式
    The following IP can be used to access Google website
    一个未排序整数数组,有正负数,重新排列使负数排在正数前面,并且要求不改变原来的 相对顺序 比如: input: 1,7,-5,9,-12,15 ans: -5,-12,1,7,9,15 要求时间复杂度O(N),空间O(1) 。
    当今世界最受人们重视的十大经典算法
    指针
    变量作用域和生存期
    一篇文章搞清spark内存管理
    Spark的Shuffle是怎么回事
    一篇文章搞清spark任务如何执行
    scala这写的都是啥?一篇文章搞清柯里化
  • 原文地址:https://www.cnblogs.com/wyxdrqc/p/10970539.html
Copyright © 2011-2022 走看看