[jzoj]3506.【NOIP2013模拟11.4A组】善良的精灵(fairy)(深度优先生成树)

Link

  https://jzoj.net/senior/#main/show/3506

Description

  从前有一个善良的精灵。
  一天,一个年轻人B找到她并请他预言他的未来。这个精灵透过他的水晶球看到这个年轻人将要遇见一个非常美丽的公主并要娶她。。精灵在一张纸上画了N个点并用一些线段将他们连起来,每条线段两端连着不同的点。画完了之后,精灵让年轻人去除一条线段。然后精灵尝试将每个点用红色或者蓝色进行染色,同时使得那里没有一条线段的两端是相同的颜色。如果精灵能够成功染色,这个预言就能成真。
  年轻人想要遇见那位公主,因此他请求你去帮助他,找到所有的删除之后能对图进行成功染色的线段。

Solution

0~99分

  显然爆搜。

100分

  题目大意就是“给你一个无向图,让你删去一条边,使得原图无奇环”

  既然考虑到环的奇偶性,自然就得考虑到其个数。按照惯例,绘制一个深度优先生成树(DFS树)

  怎么绘制呢?

  选择一个点为根,按照DFS的顺序,连出一棵树。当一个点连向一个深度小与它的点,显然,就构成了一个环。

  我们称这条边为返祖边,这个环的大小就是两点深度差+1。

  然后在树上弄一个类似差分约束的思路,来求出当前边被多少个奇数,偶数环所包括。

  

  对于一条边

  (1)全图无环或者只有一个偶环,当前边可以删  

  (2)如果不符合(1),可以删当前边,仅当当前边被这个图所有奇数环覆盖,且不被一个偶数环包括。

  引理1易证

  引理2:如果奇数和偶数环在一起,删完后一定不满足。如果不包括所有奇数环,那么在不被当前边包括的奇数环就不满足。

Code

{$inline on}
var
        n,m,i,x,y,tot,tot1,papa:longint;
        w:array[0..10000] of longint;
        dis:array[0..10000] of boolean;
        data:array[0..1000] of longint;
        pre,tov,last:array[0..20000] of longint;
        pre1,tov1,cos1,last1:array[0..10000] of longint;
        ji,ou,numj,numo:array[0..10000] of longint;
procedure insert(x,y:longint);  inline;
begin
        inc(tot);
        tov[tot]:=y;
        pre[tot]:=last[x];
        last[x]:=tot;
end;

procedure insert1(x,y,z:longint); inline;
begin
        inc(tot1);
        tov1[tot1]:=y;
        cos1[tot1]:=z;
        pre1[tot1]:=last1[x];
        last1[x]:=tot1;
end;

procedure dg(x,q,shen:longint); inline;
var
        k:longint;
begin
        dis[x]:=true;
        w[x]:=shen;

        k:=last[x];

        while k<>0 do
        begin
                if tov[k]<>q then
                begin
                        if not dis[tov[k]] then
                        begin
                                insert1(x,tov[k],(k+1) shr 1);

                                dg(tov[k],x,shen+1);
                        end
                        else
                        if w[tov[k]]<w[x] then
                        begin
                                if odd(w[tov[k]]-w[x]+1) then
                                begin
                                        inc(ji[x]);
                                        dec(ji[tov[k]]);

                                        numj[(k+1) shr 1]:=1;

                                        inc(papa);
                                end
                                else
                                begin
                                        inc(ou[x]);
                                        dec(ou[tov[k]]);

                                        numo[(k+1) shr 1]:=1;
                                end;
                        end;
                end;

                k:=pre[k];
        end;
end;

procedure find(x:longint); inline;
var
        k:longint;
begin
        k:=last1[x];

        while k<>0 do
        begin
                find(tov1[k]);

                numj[cos1[k]]:=ji[tov1[k]];
                numo[cos1[k]]:=ou[tov1[k]];

                inc(ji[x],numj[cos1[k]]);
                inc(ou[x],numo[cos1[k]]);

                k:=pre1[k];
        end;
end;
begin
        assign(input,‘fairy.in‘);reset(input);
        assign(output,‘fairy.out‘);rewrite(output);

        readln(n,m);

        for i:=1 to m do
        begin
                readln(x,y);

                insert(x,y);
                insert(y,x);
        end;

        for i:=1 to n do
                if not dis[i] then
                begin
                        dg(i,0,1);

                        find(i);
                end;

        for i:=1 to m do
                if ((numj[i]=papa) and (numo[i]=0)) or (papa=0) then
                begin
                        inc(data[0]);

                        data[data[0]]:=i;
                end;

        writeln(data[0]);

        for i:=1 to data[0] do
                write(data[i],‘ ‘);
end.
时间: 2024-11-14 13:27:35

[jzoj]3506.【NOIP2013模拟11.4A组】善良的精灵(fairy)(深度优先生成树)的相关文章

2017.11.25【NOIP提高组】模拟赛A组

2017.11.25[NOIP提高组]模拟赛A组 T1 3467. [NOIP2013模拟联考7]最长上升子序列(lis) T2 3468. [NOIP2013模拟联考7]OSU!(osu) T3 3472. [NOIP2013模拟联考8]匹配(match) T1 有转移方程f[i]=max{f[j]}+1,a[j]<a[i] 可以用线段树+离散化维护这个方程,因为涉及以往状态可以用主席树维护 打太丑爆空间了 Code 1 #include<cstdio> 2 #include<c

2017.12.09【NOIP提高组】模拟赛A组

2017.12.09[NOIP提高组]模拟赛A组 T1 3489. [NOIP2013模拟联考11]数列的GCD(gcd) T2 3500.[NOIP2013模拟联考15]物语(monogatari) T3 3501.[NOIP2013模拟联考15]消息传递(news) 吐槽:这次的题好像有点水啊,但最简单的第二题都给打挂啦!!(数组开小了) T1 本套题中最难的题.考虑dp 设f[i]是b[1],b[2]...b[N]的最大公约数的数目,g[i]是b[1],b[2]...b[N]的公约数的数目

2017.12.02【NOIP提高组】模拟赛A组

2017.12.02[NOIP提高组]模拟赛A组 T1 3555[GDKOI2014模拟]树的直径 T2 3542[清华集训2014]冒泡排序 T3 3486[NOIP2013模拟联考10]道路改建(rebuild) T1 树直径的一个性质,两棵树合并,形成新的树的直径的两个端点为原树中的四个端点之二. 可以用反证法证明.用此性质本题就变成了lca裸题了 Code #include<cstdio> #include<cstring> #include<cmath> #i

JZOJ4316【NOIP2015模拟11.5】Isfind 题解

JZOJ4316 [NOIP2015模拟11.5]Isfind 题解 Description Input Output Sample Input 4 3    acbc    abc    cba    cc Sample Output Y    N    Y Data Constraint 思路: 题意要看懂,首先声明一下"子串"和"子序列"的区别,S的"子串"意思是在S中选取任意i个(0 < i <= |S|)连续字符组成的字符串

2017.07.11【NOIP提高组】模拟赛B组

Summary 今天的比赛打得还不错,第一题被同桌灌输的贪心,纯模拟洗脑了,然后steal的看了一下,发现怎么也对不了,一直在检查.最后10分钟才找出反例,推出动态规划方程,没有想到怎么转移,比赛就结束了.第二题题意理解错误了,但是还是拿到了充满希望的10分,第三题看到题目就直接上了线段树,我想没几个人能像我一样5分钟想完并打完这道题了.贪心一定要看到反例,不能盲目去做,否则浪费了时间,更让心情愈来愈不甘. Problem T1 解题 题目大意 奶牛有P (P≤300) 道题目要做.他们的月薪是

[jzoj]3456.【NOIP2013模拟联考3】恭介的法则(rule)

Link https://jzoj.net/senior/#main/show/3456 Description 终于,在众亲们的奋斗下,最终boss 恭介被关进了库特设计的密室.正当她们松了一口气时,这个世界却发生了天翻覆地的变化:地面开始下沉,天空开始变成血红色,海水沸腾……一幅世界末日的图景.美鱼从她手中的古籍<若山牧水诗歌集>中发现了原因:白鸟は かなしからずや 空の青 海のあをにも 染まずただよふ .大(xia)意(shuo)就是狡猾的恭介在创造这个世界的时候就篡改了法则.而这个法则

算法笔记_127:蓝桥杯2017模拟赛-本科组习题解答(Java)

 目录 1 算年龄 2 猜算式 3 排列序数 4 字符串比较 5 还款计算 6 滑动解锁 7 风险度量   PS:以下代码部分仅供参考,若有不当之处,还请路过同学指出哦~ 1 算年龄 标题:算年龄 英国数学家德摩根出生于19世纪初叶(即18xx年). 他年少时便很有才华.一次有人问他的年龄,他回答说: "到了x的平方那年,我刚好是x岁". 请你计算一下,德摩根到底出生在哪一年. 题中的年龄指的是周岁. 请填写表示他出生年份的四位数字,不要填写任何多余内容. 1806 public cl

Exchange 2016集成ADRMS系列-11:组策略分发RMS模板到客户端

在分发RMS的权限模板之前,我们需要先下载office的管理模板文件,导入到组策略控制台中,然后使用导入的office组策略模板去配置RMS的相关设置. 首先我们从下面的位置下载office 2010的组策略管理模板. Download Office 2010 Administrative Template files (ADM, ADMX/ADML) and Office Customization Tool download from Official Microsoft Download

jzoj[1438]NOIP2013火柴排队

读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 2 1 4 则给他们编过号码之后,a序列也就是这样: a 2 b 3 c 1 d 4 按从小到大排序也就有 c 1 a 2 b 3 d 4 这样就把b组序列的顺序搞出来了, 然后结合归并排序求解逆序对即可