CF19E Fairy(树上差分)

2023-11-06 03:20
文章标签 树上 差分 fairy cf19e

本文主要是介绍CF19E Fairy(树上差分),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

很久很久以前,有一个仙女叫做A。有一天一个少年B找到她,并且请求她预测他的未来。仙女看着她的水晶球,说这位少年不久将遇见世界上最美丽的公主,并且将迎娶她为妻。然后仙女在一张纸上画了n个点,并把它们分为几个板块,每个板块以一些点为始,另一些点为终。画完这幅画,仙女要求少年擦掉之上的一个板块。然后她尝试给每个点画上红色或蓝色,让纸上没有板块有和它的结尾颜色一样的点。如果她能做到,这个预言将会成真。B想邂逅世界上最美丽的公主,所以他想要你帮助他。找到所有能帮助他邂逅公主的板块。

输入输出格式:

输入格式:

输入文件的第一行有两个整数:n——点数;m:板块个数。

接下来的m行有板块的描述。每一个描述有两个整数,用空格隔开——v,u——各点的编号(index),由此板块连接。没有板块在描述中会被描述两次。

输出格式:

输出文件的第一行输出数字k——答案中板块的数量。输出文件的第二行输出k个数字,以空格隔开————每个板块的编号,升序排列。每个编号只应被输出一次。板块从1开始编号,以输入的顺序为序。

题解

因为二分图没有奇环,我们就把奇环删掉就行了。

实际上需要分情况讨论:

当没有奇环时,随便删掉一条边即可。

当只有一个奇环时,删掉这个奇环上没有被偶环覆盖的边就行(因为把一个奇环和一个偶环的公共边删去还是一个奇环)

当有多条奇环时,删掉被所有奇环覆盖的且不被偶环覆盖的边。

代码细节很多具体看代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 const int maxn=500000;
 6 int n,m,sum,ans,cnt;
 7 int f[maxn],to[maxn<<1],next[maxn<<1],book[maxn<<1],head[maxn],pa[maxn],pb[maxn],vis[maxn],dep[maxn];
 8 int fa[maxn][31],Log[maxn],pc[maxn],s1[maxn],s0[maxn],from[maxn],bok[maxn];
 9 inline void add(int a,int b){
10     to[++cnt]=b;
11     next[cnt]=head[a];
12     head[a]=cnt;
13 }
14 void dfs1(int x){
15     vis[x]=1;
16     for(int i=head[x];i;i=next[i])  
17         if(!vis[to[i]])
18             book[i]=1,fa[to[i]][0]=x,dep[to[i]]=dep[x]+1,from[to[i]]=(i>>1),dfs1(to[i]);
19 }
20 int lca(int u,int v){
21     if(dep[u]<dep[v])swap(u,v);
22     for(int i=30;i>=0;i--){
23         if(dep[fa[u][i]]>=dep[v])u=fa[u][i];
24     }
25     if(u==v)return v;
26     for(int i=30;i>=0;i--){
27         if(fa[u][i]!=fa[v][i]){
28             u=fa[u][i];v=fa[v][i];
29         }
30     }
31     return fa[u][0];
32 }
33 void dfs2(int x){
34     for(int i=head[x];i;i=next[i])  
35         if(book[i])  
36             dfs2(to[i]),s1[x]+=s1[to[i]],s0[x]+=s0[to[i]];
37 }
38 int main()
39 {
40     scanf("%d%d",&n,&m);
41     cnt=1;
42     int i,j;
43     for(i=1;i<=m;i++){
44         scanf("%d%d",&pa[i],&pb[i]);add(pa[i],pb[i]);add(pb[i],pa[i]);
45     }
46     for(i=1;i<=n;i++)    if(!vis[i]) dep[i]=1,dfs1(i);
47     for(int i=1;i<=30;i++)
48         for(int j=1;j<=n;j++){
49             fa[j][i]=fa[fa[j][i-1]][i-1];
50         }
51     for(i=1;i<=m;i++)    
52     if(!book[i*2]&&!book[i*2+1]){
53         pc[i]=lca(pa[i],pb[i]);
54         if(!((dep[pa[i]]^dep[pb[i]])&1))sum++,s1[pa[i]]++,s1[pb[i]]++,s1[pc[i]]-=2;
55         else s0[pa[i]]++,s0[pb[i]]++,s0[pc[i]]-=2;
56     }
57     for(i=1;i<=n;i++)if(dep[i]==1)dfs2(i);
58     if(!sum){
59         printf("%d\n",m);
60         for(i=1;i<=m;i++)printf("%d ",i);
61         return 0;
62     }
63     if(sum==1)
64         for(i=1;i<=m;i++)
65             if(!book[i*2]&&!book[i*2+1]&&!((dep[pa[i]]^dep[pb[i]])&1))bok[i]=1,ans++;
66     for(i=1;i<=n;i++)
67         if(s1[i]==sum&&!s0[i])bok[from[i]]=1,ans++;
68     printf("%d\n",ans);
69     for(i=1;i<=m;i++)
70         if(bok[i])printf("%d ",i);
71     return 0;
72 }
View Code

 

转载于:https://www.cnblogs.com/Xu-daxia/p/9384349.html

这篇关于CF19E Fairy(树上差分)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/354207

相关文章

poj 3159 (spfa差分约束最短路) poj 1201

poj 3159: 题意: 每次给出b比a多不多于c个糖果,求n最多比1多多少个糖果。 解析: 差分约束。 这个博客讲差分约束讲的比较好: http://www.cnblogs.com/void/archive/2011/08/26/2153928.html 套个spfa。 代码: #include <iostream>#include <cstdio>#i

poj 3169 spfa 差分约束

题意: 给n只牛,这些牛有些关系。 ml个关系:fr 与 to 牛间的距离要小于等于 cost。 md个关系:fr 与 to 牛间的距离要大于等于 cost。 隐含关系: d[ i ] <= d[ i + 1 ] 解析: 用以上关系建图,求1-n间最短路即可。 新学了一种建图的方法。。。。。。 代码: #include <iostream>#include

POJ 1364差分约束

给出n个变量,m个约束公式 Sa + Sa+1 + .... + Sa+b < ki or > ki ,叫你判断是否存在着解满足这m组约束公式。 Sa + Sa+1   +   .+ Sa+b =  Sum[a+b] - Sum[a-1]  . 注意加入源点n+1 。 public class Main {public static void main(Strin

Python中差分进化differential_evolution的调用及参数说明

在场景应用中,要求我们的函数计算结果尽可能的逼近实际测量结果,可转化计算结果与测量结果的残差,通过最小化残差,便可求出最优的结果。但使用最小二乘等方法来计算时,常常会使迭代的结果显然局部最优点而导致结算错误。 差分进化原理 差分进化(Differential Evolution,DE)是一种基于群体差异的进化算法,其计算思想主要包括以下几个方面: 一、初始化种群 首先,随机生成一个初始种群

RS485差分信号不对称

在RS485总线通信中,差分信号不对称的问题时常出现,尤其是在总线未接从机设备的情况下。这一问题不仅影响通信质量,还可能导致信号传输错误。通过对实际波形、芯片手册及电路的深入分析,可以找出引发差分信号不对称的根本原因,并采取相应的解决措施。 问题描述 在RS485通信测试中,当总线上没有从机设备连接时,观察到RS485差分信号(A、B)关于地(GND)不对称。理想情况下,RS485的差分信

【POJ】3169 Layout 【HDU】3592 World Exhibition 差分约束

传送门:  【POJ】3169 Layout、【HDU】3592 World Exhibition 题目分析:我会说我只是凭直觉写的吗。。。。。。。 如果有B-A>=C形式的,则建边(B,A,-C)。 如果有B-A<=C形式的,则建边(A,B,C)。 对所有的点X,建边(X,X-1,0)。 最后跑一遍最短路。如果存在负环输出-1,如果点N不可达输出-2,否则输出点N的值(最短路径长

【codechef】 Prime Distance On Tree【求树上路经长度为i的路径条数】【点分治+FFT】

传送门:【codechef】 Prime Distance On Tree 点分治+FFT水题……竟然n*n爆int没发现…… 而且NTT TLE,FFT跑的超级快…… my  code: my~~code: #include <bits/stdc++.h>using namespace std ;typedef long long LL ;#define clr( a , x ) m

Xilinx FPGA 原语解析(二):IBUFDS差分输入缓冲器(示例源码及仿真)

目录 前言: 一、原语使用说明 二、原语实例化代码模版 三、使用示例 1.设计文件代码 2.仿真文件代码 3.仿真结果 前言: 本文主要参考资料xilinx手册,《Xilinx 7 Series FPGA and Zynq-7000 All Programmable SoC Libraries Guide for HDL Designs》UG768 (v14.7) Octob

差分、前缀和

P8218 【深进1.例1】求区间和  (前缀和) #include <bits/stdc++.h>using namespace std;int n, m, a[100010], sum[100010], ans, l, r;int main(){scanf("%d", &n);for(int i=1; i<=n; ++i){scanf("%d", &a[i]);sum[i]=sum[

差分约束题目

P5960 【模板】差分约束算法 #include <bits/stdc++.h>using namespace std;int n, m, v, u, w, dis[5001];bool flag;struct node{int from, to, weight;}edge[5001];int main(){cin >> n >> m;memset(dis, 0x3f, size