图论分类讨论 bzoj2503相框
来源:互联网 发布:哪个软件可以看英剧 编辑:程序博客网 时间:2024/05/17 01:30
问题 B: 相框
时间限制: 1 Sec 内存限制: 256 MB
题目描述
【问题描述】
P大的基础电路实验课是一个无聊至极的课。每次实验,T君总是提前完成,管理员却不让T君离开,T君只能干坐在那儿无所事事。
先说说这个实验课,无非就是把几根导线和某些元器件(电阻、电容、电感等)用焊锡焊接起来。
为了打发时间,T君每次实验做完后都在焊接一些诡异的东西,这就是他的杰作:
T君不满足于焊接奇形怪状的作品,强烈的破坏欲驱使他拆掉这个作品,然后将之焊接成规整的形状。这会儿,T君正要把这个怪物改造成一个环形,当作自己的相框,步骤如下:
T君约定了两种操作:
烧熔一个焊点:使得连接在焊点上的某些导线相分离或保持相连(可以理解为:把焊点上的导线划分为若干个类,相同类中的导线相连,不同类之间的导线相离)
将两根导线的自由端(即未与任何导线相连的一端)焊接起来。
例如上面的步骤中,先将A点烧熔,使得导线1与导线2、4点分离;再将D点烧熔,使得4、5与3、7相离;再烧熔E,使7与6、8相离;最后将1、7相连。
T君想用最少的操作来将原有的作品改造成为相框(要用上所有的导线)。
【输入文件】
输入文件的第一行共有两个整数n和m:分别表示原有的作品的焊点和导线的数量 (0 ≤ n ≤ 1 000, 2 ≤ m ≤ 50 000)。焊点的标号为1~n。
接下来的m行每行共有两个整数:导线两端所连接的两个焊点的标号,若不与任何焊点相连,则将这一端标号为0。
原有的作品可能不是连通的。
某些焊点可能只有一根导线与之相连,在该导线的这一端与其他导线相连之前,这些焊点不允许被烧熔。
某些焊点甚至没有任何导线与之相连,由于T君只关心导线,因此这些焊点可以不被考虑。
【输出文件】
输出文件只包含一个整数:表示T君需要将原有的作品改造成相框的最少步数。
【输入样例1】
6 8
1 2
1 3
3 4
1 4
4 6
5 6
4 5
1 5
【输出样例1】
4
【输入样例2】
0 2
0 0
0 0
【输出样例2】
2
【输入样例3】
3 3
0 1
0 0
2 2
【输出样例3】
4
【数据规模和约定】
30%的数据中n≤10;
100%的数据中n≤1000。
图片自己去找。。。
因为最终情况要满足所有点的度数都是2(度数一开始就是0的点直接扔掉)所以我们要对所有度数大于2的点都要被熔烧。奇数的熔成一堆2度数的点+一个单个的点。
那么现在有两种情况
1. 只有一个联通块,也就是所有边都连在一起。只要把所有度数大于2的点熔成度数<=2的点,再把所有单个的点(熔出来的+本来就有的)两两配对组一起即可。自己试一下就是这样的,所以没必要管谁和谁连了。
2. 有多个联通块,就要把所有的联通块都变成环,然后把所有环再熔成一条链,再把所有链连起来。。。对于过程中出现1度数点的联通块只要少熔和一对就好了。如果没有1度数点,但在过程中有把偶数点熔成2度数点的过程,就可以把一对2度数点熔成两个单个的就好了。
联通块用并查集就行了。
但是那堆0很令人尴尬.。。每个0新建一个点就好了。
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 101005#define inf 1000000000using namespace std;int read(){ int sum=0,f=1;char x=getchar(); while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();} while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();} return sum*f;}int n,m,tot,ans,cnt,du[N],f[N],vis[N];int s[N],p[N],belong[N];int find(int x){return f[x]==x?x:f[x]=find(f[x]);}int main(){ n=read();m=read();int x,y;tot=n; for(int i=1;i<=2*m;i++)f[i]=i; for(int i=1;i<=m;i++) { x=read();y=read(); if(x==0)x=++tot; if(y==0)y=++tot; du[x]++;du[y]++; int fx=find(x),fy=find(y); f[fx]=fy; } for(int i=1;i<=tot;i++) { if(du[i]==0)continue; int fx=find(i); if(!vis[fx])vis[fx]=++cnt; belong[i]=vis[fx]; } if(cnt==1) { int sum=0; for(int i=1;i<=tot;i++) { if(!du[i])continue; if(du[i]==1){sum++;continue;} if(du[i]&1){sum++;ans++;continue;} if(du[i]>2&&du[i]%2==0){ans++;} } printf("%d\n",ans+sum/2); } else { ans+=cnt; for(int i=1;i<=tot;i++) { if(!du[i])continue; if(du[i]==1){s[belong[i]]++;continue;} if(du[i]&1){s[belong[i]]++;ans++;p[belong[i]]=1;continue;} if(du[i]>2){ans++;p[belong[i]]=1;} } for(int i=1;i<=cnt;i++) { if(s[i]>0){ans+=s[i]/2-1;continue;} if(p[i]==0)ans++; } printf("%d\n",ans); }}
- 图论分类讨论 bzoj2503相框
- BZOJ 2503 相框 分类讨论
- 分类讨论
- hdu5105Math Problem(分类讨论)
- UOJ295,大力分类讨论
- Codeforces R278 div2B 分类讨论
- Finals in arithmetic 分类讨论
- codeforces 789B(分类讨论)
- bzoj1177 [Apio2009] Oil 分类讨论
- NLP 分类问题的讨论
- HDU 1061 Rightmost Digit(分类讨论)
- GCJ 2015R1B(Noisy Neighbors-分类讨论)
- 【HDU】5296 Annoying problem【树链剖分+分类讨论】
- BZOJ 1141 [POI2009]Slw 分类讨论
- hdu5399 Too Simple(推论,分类讨论)
- CodeForces 44B- A - Cola- 分类讨论
- BZOJ-1067 降雨量 线段树+分类讨论
- 【SRM 565 UnknownTree】计数 分类讨论
- 高精+卡特兰数 bzoj3907网格
- 无法链接MySQL数据库
- wireshark抓包的一些命令
- hiho 1599 dfs乱搞 [Offer收割]编程练习赛29 Problem A 逃离迷宫4
- C++子类对象隐藏了父类的同名成员函数(隐藏篇)
- 图论分类讨论 bzoj2503相框
- Eclipse编译时保留方法的形参<转>
- ConCurrent包下工具类-CyclicBarrier
- POJ 1741 Tree (树分治模板题)
- 大学生职业生涯规划
- Non-ASCII character '\xb3' in file e:\python\ship.py on line 6, but no encoding declared;
- POJ3169(差分约束系统)
- 关于C++子类父类成员函数的覆盖和隐藏
- woj 1124 最大流