Codeforces 453C Little Pony and Summer Sun Celebration dfs树上构造

题目链接:点击打开链接

题意:

给定一个无向图

任选一个起点,使得访问每个点的次数奇偶与最后一行的输入一致

思路:

选一个奇数点作为起点

dfs树一下,若子节点不满足则先走到子节点再回来

如此就能保证所有子节点合法

这样dfs结束后最多只有根节点不满足,随便找一个与根相连的点调整一下。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <queue>
#include <set>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define ll int
#define N 100005
#define inf 10000009
vector<int>G[N],ans, one, tmp;
int n, m;
int a[N], st, dis[N], pre[N];
void go(int u, int v, vector<int>&x){// v - u
    x.push_back(v);
    while(1){
        v = pre[v];
        x.push_back(v);
        if(v==u)return ;
    }
}
int vis[N], hehe[N];
void dfs(int u, int fa){
    hehe[u] = fa;
    ans.push_back(u);
    vis[u] ^= 1;
    for(int i = 0; i < G[u].size(); i++)
        if(hehe[G[u][i]]==0)
        {
            dfs(G[u][i], u);
            if(a[G[u][i]] != vis[G[u][i]])
            {
                ans.push_back(u);
                ans.push_back(G[u][i]);
                vis[G[u][i]]^=1;
                vis[u] ^= 1;
            }

        if(ans[ans.size()-1] != u){ans.push_back(u); vis[u]^=1;}
        }
}

void input(){
    one.clear();
    for(int i = 0; i <= n; i++)G[i].clear();
    while(m--){
        int u, v;
        scanf("%d %d",&u,&v);
        G[u].push_back(v);      G[v].push_back(u);
    }
    st = -1;
    for(int i = 1; i <= n; i++){
        scanf("%d",&a[i]);
        if(a[i])
        {
            if(st==-1)st = i;
            one.push_back(i);
        }
    }
}
int main(){
    int i, j, u, v;
    while(~scanf("%d %d",&n,&m))
    {
        input();
        if(st == -1)  {puts("0");continue;}
        if(one.size()==1){printf("1\n%d\n", st);continue;}
        ans.clear();
        memset(vis,0,sizeof vis);
        memset(hehe, 0, sizeof hehe);
        hehe[st] = st;
        dfs(st, st);
        if(a[st]!=vis[st]){
            ans.push_back(G[st][0]);
            ans.push_back(st);
            ans.push_back(G[st][0]);
        }
        bool ok = false;
        for(i = 1; i <= n; i++)if(a[i] && hehe[i] == 0)ok = true;
        if(ok){puts("-1");continue;}

        printf("%d\n",ans.size());
        for(i = 0; i < ans.size(); i++)printf("%d ",ans[i]);puts("");
        //memset(a, 0, sizeof a);       for(i = 0; i < ans.size(); i++)a[ans[i]]^=1;        for(i = 1; i <=n ;i++)printf("%d ", a[i]);puts("");
    }
    return 0;
}

Codeforces 453C Little Pony and Summer Sun Celebration dfs树上构造,布布扣,bubuko.com

时间: 2024-08-04 21:15:16

Codeforces 453C Little Pony and Summer Sun Celebration dfs树上构造的相关文章

Codeforces 453C Little Pony and Summer Sun Celebration(构造)

题目链接:Codeforces 453 Little Pony and Summer Sun Celebration 题目大意:n个节点,m条边,然后m行给定边,最后一行表示每个节点需要进过的次数为奇数次还是偶数次. 解题思路:构造,任意从一个奇数点开始(统一森林的处理),然后每次向下遍历没有经过的节点,并且回溯,每次回溯都要判断一下刚才走过的点满不满足条件,不满足的话就再走一次.最后对于根节点,最后一次回溯要不要走根据当前走过的次数决定. #include <cstdio> #include

Codeforces 453B Little Pony and Harmony Chest(状压)

题目链接:Codeforces 453B Little Pony and Harmony Chest 题目大意:给定一个序列a, 求一序列b,要求∑|ai?bi|最小.并且b中任意两数的最大公约束为1. 解题思路:因为b中不可能含有相同的因子,所以每个素数只能使用1次.又因为说ai最大为30,所以素数只需要考虑到57即可.因为即使对于30而言,59和1的代价是一样的. 所以有dp[i][j]表示的是到第i个数,使用过的素数j. #include <cstdio> #include <cs

Codeforces 453B Little Pony and Harmony Chest 状压dp

题目链接:点击打开链接 b的数字最多只能达到59,因为选>=60 不如选1 所以状压一下前面出现过的素数即可,在59内的素数很少 然后暴力转移.. #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <string.h> const int Inf = (int)(1e9); const int S = 1 <<

Codeforces 453A Little Pony and Expected Maximum 概率题Orz

题目链接:点击打开链接 #include <stdio.h> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; int main() { int i, j; double m,n; while(cin>>m>>

Codeforces 446B DZY Loves Modification 矩阵行列分开考虑 优先队列+构造

题目链接:点击打开链接 题意: 给定n行m列的矩阵 k次操作,一个常数p ans = 0; 对于每次操作 可以任选一行或一列, 则ans += 这行(列)的数字和 然后这行(列)上的每个数字都-=p 问最大的ans 思路: 首先我们设最终选了 行 i 次,则列选了 k-i 次 那么假设我们先全部选行,然后选列,则每次选列时,要-= i*p 这样最后是 -= i*(k-i)*p 也就是所有行对列的影响 那我们先把这个 i*(k-i)*p 提出来,那么选行和选列就互不影响 就可以分别考虑行和列 对于

Codeforces 453B Little Pony and Harmony Chest:状压dp【记录转移路径】

题目链接:http://codeforces.com/problemset/problem/453/B 题意: 给你一个长度为n的数列a,让你构造一个长度为n的数列b. 在保证b中任意两数gcd都为1的情况下,使得 ∑|a[i]-b[i]|最小. 让你输出构造的数列b. (1<=n<=100, 1<=a[i]<=30) 题解: 因为1<=a[i]<=30,所以有1<=b[i]<=60,此时才有可能最优. 因为b中任意两数gcd为1,所以对于一个质因子p[i]

Codeforces 454C - Little Pony and Expected Maximum

454C - Little Pony and Expected Maximum 思路: m面的骰子掷n次,总共有m^n种情况,如果一种情况的最大值是m,那么它肯定包含m,那我们在所有情况下挖掉不包含m的情况:(m-1)^n,所以最大值是m的情况数是m^n-(m-1)^n,同理可得最大值是m-1的情况数是(m-1)^n-(m-2)^n.... 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #define

Codeforces 454D - Little Pony and Harmony Chest

454D - Little Pony and Harmony Chest 思路: 状压dp,由于1的时候肯定满足题意,而ai最大是30,所以只要大于等于59都可以用1替换,所以答案在1到59之间 然后筛出1到58之间的质数,只有16个,把1到58的数的状态由这16个质数表示,如果整除这个质数则二进制中这一位为1,否则则为0 状态:dp[i][j]表示到第i个数为止选取的数的状态为j的最小差和 初始状态:dp[0][0]=0 状态转移: dp[i+1][j|sta[k]]=min(dp[i+1][

CodeForces 453A Little Pony and Expected Maximum

题意: n面骰子掷m次,求最大值的期望. 别人的做法:最大值为i的概率=所有点数<=i的概率-所有点数<=i-1的概率,然后直接算. sb做法:精度要求1e-4,而m较大时最大值是一个较小数的概率非常小,精度范围内不影响答案,所以直接dp,f[i][j]表示掷了i次之后最大值为j的概率,通过前缀和优化做到O(n)转移 方程为f[i][j]=(f[i-1][1]+f[i-1][2]+f[i-1][3]+-.+f[i][j-1])*(1/n)+f[i-1][j]*(j/n) 因为点数越小概率越小所