◆例题·6◆ 电压机制

周六日常模拟赛……已经不知道该说什么了(感觉做不出来的都是好题)


▷ 题目

(终于不用自己翻译英文题了╮(╯-╰)╭)

【问题描述】

科学家在“无限神机”(Infinity Machine)找到一个奇怪的机制,这个机制有N个元件,有M条电线连接这些元件,所有元件都是连通的。两个元件之间可能有多条电线连接。

科学家对这些元件可以任意地设置为“高电压”和“低电压”两种模式,如果一条电线的一端为高电压,另一端为低电压,这条电线就会产生电流。

为了安全的研究“无限神机”,科学家需要找到一条电线,将它的两端设为相同的电压,并且除选择的这条电线外,其它所有电线都有电流(否则就没有研究的价值了)。

有多少条电线满足这样的条件?

【输入格式】

从文件 voltage.in 中读入数据。

输入的第一行包含两个正整数 n, m ,表示元件数和电线数。

接下来 m 行,每行两个整数 u, v,表示元件 u 和元件 v 有一条电线连接

【输出格式】

输出到文件 voltage.out 中。

输出一个整数,表示有多少条电线满足条件。

(鬼畜的题目背景就不copy上来了U•ェ•*U)


▷ 解析

首先很容易想到,节点的高/低电压就相当于0/1染色,除了题目所提到的“被选择的电线”,其他的边的两个端点的颜色应该不同。听起来是不是特别像二分图?所以可以套用一下判断二分图的DFS……检查是否染色成功。

接下来考虑一下图上的一些性质——环!

① 如果没有环

那么就非常简单了,由于图是全联通的,所以此时图就是一棵树。那么每一条边都可以作为“被选中的边”。原因是:

选择一条边就相当于把它删去,同时将它的两端点染成相同的颜色。但是由于图是一棵树,删除任意一条边都会将树分成两个连通块,两个连通块分别形成一个新的树。既然是树,从一个点开始,就一定可以将整棵树都染上色。

那么上述情况,答案就是边的数量。

 如果有偶环

很容易想到不能选择在偶环上的边,否则染色就会失败。

比如下面这个例子:

③ 如果有奇环

可以想到选择的边一定要在奇环中,否则会出现下面这种情况:{1,2,3,4,5}构成一个奇环,但是选择了1->6的边,也就相当于从1开始对奇环染色……很明显是无法完成的。

推广一下,对于每一个奇环,只要它没有一条边被选中,它就一定会从它的某一个点开始染色,而这样染色的结果就只有失败。所以所有奇环都必须包含有被选择的边,换句话说,如果我们计算出所有奇环的边集——我们能选择的边就只能是所有奇环的边集的交集!

综上所述,除了情况①,我们要选择的边E要满足以下性质:

1. 设第i个偶环的边集为 A[i] ,则对于每一个i, E ∉ A[i]

2. 设第i个奇环的边集为 B[i] ,则对于每一个i, E ∈B[i]

接下来就是进行一个DFS。由于下面要用到 DFS 树的一些知识,初学者可以先学一下 DFS树(不然可能会自闭(。・∀・)ノ)。

说明一下变量:

1. 整个图的奇环的个数为 odd。

2. 对于一条边存储一个 tot 值表示该边在多少个奇环内,则判断该边是否满足“包含在任何一个奇环内”时,只需要判断它的 tot 是否等于 odd 就可以了。

3. cnt[u] 表示 u 到 u的父亲(在DFS树里) 这一条边包含在多少个奇环里(差分数组)。

从1节点开始DFS,同时进行二分图染色。假设当时在节点u,准备扩展到与u相连的节点v —— 如果v没有染色,就将v染色,继续从v扩展;如果v已经染过色,那么 u->v 是一条返祖边,众所周知,u->v 的返祖边与 u->v 在DFS树上的路径会围成一个环。对于围成环的情况,判断当 u的颜色 和 v的颜色 相同时,就围成了一个奇环,否则围成了一个偶环。如果围成了一个奇环,则将环内的所有边的 tot 都+1;如果围成偶环,则将环内的所有边的 tot 都-1,这样的话 tot 就不可能达到 odd,也就不可能被选择了。

即使上述算法已经比较优秀了,但是仍然会爆炸,因为枚举环上的边时间复杂度太大了!

所以我们需要用到差分,差分数组最显著的性质就是 前缀和 等于原数组。当找到环时,如果是奇环,则 cnt[u]++,cnt[v]--,同时将 u->v 这条返祖边的 tot +1;如果是偶环,则 cnt[u]--,cnt[v]++,同时将 u->v 这条返祖边的 tot -1。除了在找到环时更改 cnt,在回溯时,父亲和儿子之间也存在 cnt 的转换——假设 点u,v 在DFS树中 u 是 v 的父亲,则 cnt[u]+=cnt[v] ,且 u->v 这一条树边的 tot 也 +=cnt[v]。

当整个 DFS 结束后,枚举所有边,判断它的 tot 是否等于 odd,如果是,则 ans++。

(我猜可能有一些 reader 已经自闭了,还是看看代码吧)


▷ 源代码

  1. /*Lucky_Glass*/
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. const int N=100000,M=200000;
  5. struct EDGE{
  6. int u,v;
  7. }edg[M+5];
  8. struct LINK{
  9. int v,id;
  10. };
  11. vector< LINK > lnk[N+5];
  12. int n,m;
  13. bool vis[M+5];
  14. int col[N+5],cnt[N+5],tot[M+5],odd;
  15. void DFS(int u){
  16. for(int i=0;i<lnk[u].size();i++) //枚举相邻的点
  17. if(!vis[lnk[u][i].id]){ //这条边没有被访问过(防止走重)
  18. vis[lnk[u][i].id]=true;
  19. int v=lnk[u][i].v;
  20. if(col[v]!=-1){ //经过返祖边
  21. if(col[v]==col[u]){
  22. odd++; //奇环数量+1
  23. cnt[u]++;cnt[v]--; //差分数组 u->v 的路径+1
  24. tot[lnk[u][i].id]++; //返祖边+1
  25. }
  26. else{
  27. cnt[v]++;cnt[u]--; //u->v路径-1,相当于取消选择 u->v 路径上任何一条边的可能性
  28. tot[lnk[u][i].id]--; //取消选择返祖边的可能性
  29. }
  30. }
  31. else{
  32. col[v]=!col[u]; //染反色
  33. DFS(v);
  34. tot[lnk[u][i].id]+=cnt[v]; //父亲儿子之间的边统计
  35. cnt[u]+=cnt[v]; //差分前缀和
  36. }
  37. }
  38. }
  39. int main(){
  40. freopen("voltage.in","r",stdin);
  41. freopen("voltage.out","w",stdout);
  42. scanf("%d%d",&n,&m);
  43. for(int i=1;i<=m;i++){
  44. scanf("%d%d",&edg[i].u,&edg[i].v);
  45. lnk[edg[i].u].push_back((LINK){edg[i].v,i}); //双向连边
  46. lnk[edg[i].v].push_back((LINK){edg[i].u,i});
  47. }
  48. memset(col,-1,sizeof col); //初始化所有颜色为-1
  49. col[1]=0; //从节点1开始,先将它染成0
  50. DFS(1);
  51. int ans=0;
  52. for(int i=1;i<=m;i++)
  53. ans+=int(tot[i]==odd);
  54. printf("%d\n",ans);
  55. return 0;
  56. }

  


The End

Thanks for reading!

- Lucky_Glass

(Tab:如果我有没讲清楚的地方可以直接在邮箱lucky_glass@foxmail.com email我,在周末我会尽量解答并完善博客~)

【例题收藏】◇例题·6◇ 电压机制(voltage)的更多相关文章

  1. csps模拟85表达式密码,电压机制,括号密码题解

    题面:https://www.cnblogs.com/Juve/articles/11733280.html 表达式密码: 是个水题... #include<iostream> #incl ...

  2. 【例题收藏】◇例题·IV◇ Wooden Sticks

    ◇例题·IV◇ Wooden Sticks 借鉴了一下 Candy? 大佬的思路 +传送门+ (=^-ω-^=) 来源:+POJ 1065+ ◆ 题目大意 有n个木棍以及一台处理木棍的机器.第i个木棍 ...

  3. 【例题收藏】◇例题·V◇ Gap

    ◇例题·V◇ Gap 搜索训练开始了……POJ的数据比ZOJ强多了!!看来不得不写正解了 +传送门+ ◇ 题目 <简要翻译> 有一个四行九列的矩阵——在第1~4行.2~8列上填上数字 11 ...

  4. 【例题收藏】◇例题·III◇ 木と整数 / Integers on a Tree

    ◇例题·III◇ 木と整数 / Integers on a Tree 只需要一个美妙的转换,这道题就会变得无比美妙…… 来源:+AtCoder 2148(ARC-063 E)+ ◆ 题目大意 给定一棵 ...

  5. 【例题收藏】◇例题·II◇ Berland and the Shortest Paths

    ◇例题·II◇ Berland and the Shortest Paths 题目来源:Codeforce 1005F +传送门+ ◆ 简单题意 给定一个n个点.m条边的无向图.保证图是连通的,且m≥ ...

  6. 【例题收藏】◇例题·I◇ Snuke's Subway Trip

    ◇例题·I◇ Snuke's Subway Trip 题目来源:Atcoder Regular 061 E题(beta版) +传送门+ 一.解析 (1)最短路实现 由于在同一家公司的铁路上移动是不花费 ...

  7. [CSP-S模拟测试]:电压机制(图论+树上差分)

    题目描述 科学家在“无限神机”($Infinity\ Machine$)找到一个奇怪的机制,这个机制有$N$个元件,有$M$条电线连接这些元件,所有元件都是连通的.两个元件之间可能有多条电线连接.科学 ...

  8. 收藏:Windows消息机制

    百度百科介绍的windows消息机制也不错:http://baike.baidu.com/view/672379.htm Windows的应用程序一般包含窗口(Window),它主要为用户提供一种可视 ...

  9. 收藏:Win32消息机制

    Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个 ...

随机推荐

  1. XML深入了解(XML JavaSprint)

    XMLHttpRequest 对象 XMLHttpRequest 对象用于在后台与服务器交换数据. XMLHttpRequest 对象是开发者的梦想,因为您能够: 在不重新加载页面的情况下更新网页 在 ...

  2. flex布局的一些注意点

    现在来总结下自己在项目中用flex布局的一些注意点 1.ui图中的布局方式与justify-content的布局方法不一样 这是就要利用flex-grow的空dom来分开子容器来达到页面布局的效果 2 ...

  3. 【阿里云产品公测】服务器测性能,PTS多快好省

    作者:阿里云用户goldsix PTS(性能测试服务)的官方定位是:集测试机管理.测试脚本管理.测试场景管理.测试任务管理.测试结果管理为一体的性能云测试平台.  不管定义是否高大上,一般用户尤其是我 ...

  4. ImageLoader简单使用

    效果图就是一个从网络加载的图片:在加载的时候图片的中间显示一个进度条 数据是随便找的一个网络图片的地址 导入jar包universal-image-loader-1.9.5 用来展示商品使用    在 ...

  5. Protobuf协议的Java应用例子

    Protobuf协议,全称:Protocol Buffer 它跟JSON,XML一样,是一个规定好的数据传播格式.不过,它的序列化和反序列化的效率太变态了…… 来看看几张图你就知道它有多变态. Pro ...

  6. Browser进程和浏览器内核(Renderer进程)的通信过程

    看到这里,首先,应该对浏览器内的进程和线程都有一定理解了,那么接下来,再谈谈浏览器的Browser进程(控制进程)是如何和内核通信的, 这点也理解后,就可以将这部分的知识串联起来,从头到尾有一个完整的 ...

  7. php 四种基本排序算法

    冒泡排序 思路分析:法如其名,就是像冒泡一样,每次从数组当中 冒一个最大的数出来. 第一轮:从第一个到最后一个冒泡比较,运行结果:最后一个最大 第二轮:从第一个到倒数第二个冒泡比较, 运行结果:最后一 ...

  8. day1 python 介绍、基本语法、流程控制

    请查看我的云笔记链接: http://note.youdao.com/noteshare?id=0ea7425d3e3669800cb0d73f7ec8865d&sub=D87B4BF820C ...

  9. 计算次数,POJ(1207)

    题目链接:http://poj.org/problem?id=1207 #include <stdio.h> #include <algorithm> using namesp ...

  10. 2018.10.31 Mac下的Mysql修改字符编码修改的问题总结

    今天在弄数据库的时候发现存入中文汉字变成了问号,Mac跟windows处理方式不一样. show variables like '%char%'; 查看当前mysql的编码格式 也就是默认编码格式 + ...