题目大意:给定一张无向图,每次可以进行以下两种操作: 
1.将一个点分裂成一些点,原先这个点连接的每条边任选一个新点进行连接 
2.将两个度数为1的点合并为1个点 
求将这个图变成一个环的最小操作次数

我们简单画一画可以发现,整个的答案只与度有关。 
如果最后形成了一个环。 
那么环上的点的度一定为2 
不在环上的点则都为不连边的点,度一定为0 
我们一定要拆了所有度大于2的点。 
首先忽略所有度为0的点。 
现在考虑所有的边都在一个连通块内的情况。 
对于一个度大于2的点。 
如果他的度是奇数,那么一定拆成了一堆度为2的点与一个度为1的点。 
如果他的度是偶数,那么一定拆成了一堆度为2的点。 
拆完所有度大于2的点之后。 
度为1的点一定有偶数个,只需要每一次合并两个即可。 
然后我们考虑边不都在一个连通块的情况 
即度不为0的点构成了几个连通块。 
那么对于每一个连通块,我们一定是把这个连通块搞成有两个度为1的点,其余的块内点的度均为2。 
所以这时候与上一种情况有区别的是,上一种情况可能存在操作或者不操作后块内所有的点的度都为2,这时候我们要标记是否拆分了点,因为如果拆分过点的话我们还可以拆分成两个度为1的点,和一堆度为2的点,这只用了一次操作,如果我们后拆的话会多一次操作,注意这里即可。 
其余的正常做。

 #include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio> #define N 200007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,ans,blo;
int bel[N],flag[N],vis[N],du[N],odd[N];
int cnt,hed[N],rea[N],nxt[N]; void add(int u,int v)
{
nxt[++cnt]=hed[u];
hed[u]=cnt;
rea[cnt]=v;
}
void dfs(int u,int blo)
{
vis[u]=,bel[u]=blo;
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i];
if (vis[v])continue;
dfs(v,blo);
}
}
int main()
{
memset(hed,-,sizeof(hed));
n=read(),m=read();
for(int i=;i<=m;i++)
{
int x=read(),y=read();
if(x==)x=++n;
if(y==)y=++n;
add(x,y),add(y,x);
du[x]++,du[y]++;
}
for (int i=;i<=n;i++)
if (!vis[i]&&du[i]!=)
{
blo++;
dfs(i,blo);
}
for (int i=;i<=n;i++)
if (du[i]==)
{
odd[bel[i]]++;
if(odd[bel[i]]==) ans++,odd[bel[i]]=;
}
for (int i=;i<=n;i++)
{
if(!du[i])continue;
if(du[i]>)
{
ans++;
du[i]=(du[i]&?:);
if(du[i]==)
{
odd[bel[i]]++;
if(odd[bel[i]]==)ans++,odd[bel[i]]=;
}
else flag[bel[i]]=;
}
}
if(blo!=)
{
for (int i=;i<=blo;i++)
if (!odd[i]&&!flag[i])ans++;
ans+=blo;
}
else if (odd[]!=)ans++;
printf("%d\n",ans);
}

最新文章

  1. linux指定nologin用户执行命令
  2. 用批处理批量编译多个解决方案(.sln)
  3. 1920.154s 0.309s 30817
  4. 聊天界面之气泡文本cell(二)使用Autolayout
  5. jdk线程的简单使用
  6. erl_0012 timer:tc 测试模块函数调用运行耗时
  7. 99. Recover Binary Search Tree
  8. Eclipse MAT: Understand Incoming and Outgoing References
  9. 访问MySQL数据库时,报“找不到请求的 .net Framework 数据提供程序。可能没有安装。”的解决方案
  10. [Android学习笔记]枚举与int的转换
  11. 哈尔特征Haar
  12. [matlab] 22.matlab图论实例 最短路问题与最小生成树 (转载)
  13. 设计模式理解(九)结构型——外观(Facade)
  14. BZOJ3718[PA2014]Parking——树状数组
  15. WCF:又是枚举惹的祸
  16. Python-OpenCV基本操作cv2
  17. 1.2环境的准备(二)之Pycharm的安装和使用
  18. C# 获取客户端信息 /asp.net/WebService/WebForm
  19. 【PHP】通过header发送自定义数据
  20. Ubuntu 16.04安装Eclipse并创建桌面快捷方式

热门文章

  1. 梁勇(Danniel Liang) java教材例题:java程序购买额按税率求营业税 java中数值保留2位小数的方法
  2. 更改zabbix-server的端口
  3. 【转】C++ 值传递、指针传递、引用传递详解
  4. 认识mysql(4)
  5. 网络编程-osi七层
  6. 【JS】JS实现时间戳转换成普通时间
  7. Python中列表的深浅拷贝
  8. P1309 瑞士轮
  9. 读书笔记jvm探秘之二: 对象创建
  10. OpenCV学习笔记(三) 访问像素