time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output

An undirected graph is called a caterpillar if it is a connected graph without cycles and it has such a path p that any vertex is located at a distance of at most 1 from the path p. The caterpillar can contain loops (edges from a vertex to itself) but cannot contain multiple (parallel) edges.

The picture contains an example of a caterpillar:

You are given an undirected graph G. You are allowed to do a merging operations, each such operation merges two vertices into one vertex. For that two any vertices a and b (a ≠ b) are chosen. These verteces are deleted together with their edges (which are incident to at least one of the vertices a or b) but a new vertex w is added together with edges (x, w) for each edge (a, w) and/or (b, w). If there was the edge (a, b) it transforms to the loop (w, w). The resulting graph (after the merging operation) may contain multiple (parallel) edges between pairs of vertices and loops. Let us note that this operation decreases the number of vertices of graph by 1 but leaves the number of edges in the graph unchanged.

The merging operation can be informally described as a unity of two vertices of the graph into one with the natural transformation of the graph edges.

You may apply this operation consecutively and make the given graph to be a caterpillar. Write a program that will print the minimal number of merging operations required to make the given graph a caterpillar.

Input

The first line contains a pair of integers nm (1 ≤ n ≤ 2000;0 ≤ m ≤ 105), where n represents the number of vertices in the graph andm is the number of edges in it. Then the following m lines contain edge descriptions, one edge description per line. Every line contains a pair of integers ai, bi (1 ≤ ai, bi ≤ n;ai ≠ bi), ai, bi which represent the indices of the vertices connected by the edge. The vertices are numbered from 1 to n. In the given graph it will be no more than one edge between any pair of vertices. The given graph is not necessarily connected.

Output

Print the minimal required number of operations.

Examples
input
4 4
1 2
2 3
3 4
4 2
output
2
input
6 3
1 2
3 4
5 6
output
2
input
7 6
1 2
2 3
1 4
4 5
1 6
6 7
output
1

缩点

  目标状态是一棵树,可以有自环,不能有重边。tarjan缩点后,原图形成一片森林,对于每一棵树,它最多可以保留点数res=直径上的点数+其他叶子结点树。处理森林中的每一棵树,ans=total-res

_____

  刚开始没察觉到有森林,按照树处理,WA飞

  之后因为缩点后重边加多了,T飞

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int mx[]={,,,-,};
const int my[]={,,,,-};
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
struct edge{
int v,nxt;
}e[];
int hd[mxn],mct=;
void add_edge(int u,int v){
e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
}
int mp[mxn][mxn];
int n,m;
int dtime=;
int low[mxn],dfn[mxn];
int belone[mxn],cnt;
int st[mxn],top=;
void tarjan(int u,int fa){
dfn[u]=low[u]=++dtime;
st[++top]=u;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fa)continue;
if(!dfn[v]){
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
cnt++;
int v=;
do{
v=st[top--];
belone[v]=cnt;
}while(v!=u);
}
return;
}
vector<int>eg[mxn];
int dis[mxn];
bool vis[mxn];int kct=;
int tg=;
void DFS(int u,int fa){
vis[u]=;
dis[u]=dis[fa]+;
if(dis[u]>dis[tg])tg=u;
for(int i=;i<eg[u].size();i++){
int v=eg[u][i];
if(v==fa)continue;
DFS(v,u);
}
return;
}
int pos1,pos2;
int outd[mxn];
int solve(){
if(cnt==)return n-;
int i,j;
for(i=;i<=n;i++){
for(j=hd[i];j;j=e[j].nxt){
int v=e[j].v;
if(mp[belone[i]][belone[v]])continue;
if(belone[i]!=belone[v]){
eg[belone[i]].push_back(belone[v]);
mp[belone[i]][belone[v]]=;//防止加重边
outd[belone[i]]++;
}
}
}
int res=;
for(i=;i<=cnt;i++)if(outd[i]==) res++;//叶子节点数
for(i=;i<=cnt;i++){
if(vis[i])continue;
kct++;//联通块计数
//
tg=;
DFS(i,);
pos1=tg;
tg=;
DFS(pos1,);
pos2=tg;
//求直径
if(dis[pos2]<)res++;
else res+=dis[pos2]-;
}
return n-res+kct-;
}
int main()
{
n=read();m=read();
int i,j,u,v;
for(i=;i<=m;i++){
u=read();v=read();
add_edge(u,v);
add_edge(v,u);
}
for(i=;i<=n;i++)
if(!dfn[i])tarjan(i,);
int ans=solve();
printf("%d\n",ans);
return ;
}

CodeForces 51F Caterpillar的更多相关文章

  1. Educational Codeforces Round 10 A. Gabriel and Caterpillar 模拟

    A. Gabriel and Caterpillar 题目连接: http://www.codeforces.com/contest/652/problem/A Description The 9-t ...

  2. codeforces 652A A. Gabriel and Caterpillar(水题)

    题目链接: A. Gabriel and Caterpillar time limit per test 1 second memory limit per test 256 megabytes in ...

  3. CodeForces 652A Gabriel and Caterpillar

    简单模拟. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> ...

  4. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  5. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  6. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  7. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  8. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  9. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

随机推荐

  1. 注册URL模式与HttpHandler的映射关系

    注册URL模式与HttpHandler的映射关系 ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHan ...

  2. NOI2018准备 Day9

    tjvj清北入学测试又打了一上午,暴力搜索得了部分分,dp全崩了,8道题凑了500分. 下午打了个速度赛,成绩未知,另外又做了1道题,这效率low到爆!!!

  3. SQL Server 用SSMS查看依赖关系有时候不准确,改用代码查

    SQL Server 用SSMS查看依赖关系有时候不准确,明明某个sp中有用到表tohen,查看表tohen的依赖关系的时候,却看不到这个sp 用代码查看方式如下: --依赖于表tohen的对象 SE ...

  4. Oracle 常用函数

    主要是对项目中用过的 oracle 函数进行总结,并做出目录,方便后续项目是快速查找,提高效率. 01.Round (数值的四舍五入) 描述:传回一个数值,该数值是按照指定的小数位元数进行四舍五入运算 ...

  5. 如何用 Nodejs 分析一个简单页面

    本文目的 在浏览器地址栏中输入 localhost:3000,在页面显示 博客园首页 的 20 篇文章标题. 过程分析 首先需要端口的监听,这就需要引入 Node 中最重要的模块之一 express. ...

  6. 利用PowerShell+Jenkins,实现项目的自动化部署

    当项目越来越庞大,部署环境越来越多以后,就会越来越依赖于自动化.比如本人公司的项目,目前有6个web和4个windows service,同时本地有两套环境:开发自测试环境和QA测试环境.每次版本发布 ...

  7. ul、li模仿ios的TableView实现城市选择

    最近项目一个接着一个,之前说的精创环的项目还没做完,今天说先把那个放一下,先做访客系统,销售会见客户之后可以对客户进行一个跟踪记录,原型图也给了,今日头条的频道自定义页面一样. 如果是在IOS上让我来 ...

  8. 从语言到库到框架,再到API,再到标记最后到DSL语言

    计算机技术发展很快,而且越来越快,结果也是越来越复杂,那么我们到底怎么搞定复杂性并重用代码? 很明显,这是个大难题.一开始我们要解决计算问题,发展了基本的编程语言. 很快,编程语言不能满足需求,我们需 ...

  9. EditPlus怎样自动换行

    如果只是使用快捷键Ctrl+Shift+W或者使用文档→自动换行,的话,关闭软件之后再次打开时就会重新出现不能自动换行的问题. 中文版的是:文档→固定值设置(文档 菜单的最后一个),会打开一个“工具→ ...

  10. Jquery-EasyUI学习2~

    下面这个Demo用的是MVC+Ado.Net.存储过程 实现功能:分页查询,添加.修改功能.模糊查询功能 先来几张效果图: 创建存储过程如下 go create proc usp_FenYe2 @se ...