【Codeforces Beta Round #48】 Codeforces 51F Caterpillar

来源:互联网 发布:乔任梁死因分析知乎 编辑:程序博客网 时间:2024/05/22 10:24

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�6�5≠�6�5b) 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,�6�5w) for each edge (a,�6�5w) and/or
(b,�6�5w). If there was the edge (a,�6�5b) it transforms to the loop
(w,�6�5w). 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 n, m
(1�6�5≤�6�5n�6�5≤�6�52000;0�6�5≤�6�5m�6�5≤�6�5105), where n represents
the number of vertices in the graph and m 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,�6�5bi
(1�6�5≤�6�5ai,�6�5bi�6�5≤�6�5n;ai�6�5≠�6�5bi), ai,�6�5bi 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.

首先注意到,环一定不会存在,所以可以先缩点成森林。对于每棵树,找到留下的链,那么除了叶子节点之外的所有点都要消掉,所以应该取最长链,这样对于一块大小为n的联通块,花费为n-叶子数-最长链点数+2【因为链上两个端点的点被算了两次】。最后连通起来,只需要把每一块的链首尾相连,所以花费为联通块个数-1。注意联通块个数和联通块数量是可以一起算的,最后特判一下孤立点的情况。

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;int f1[2010],n1[200010],t1[200010],bel[200010],dfn[200010],low[200010],sta[2010],m,n,num,clo,top;bool have[2010][2010],vis[2010];vector<int> to[2010];void add(int num,int u,int v){    n1[num]=f1[u];    f1[u]=num;    t1[num]=v;}void dfs1(int u,int fa){    int i,v,x;    dfn[u]=low[u]=++clo;    sta[++top]=u;    for (i=f1[u];i;i=n1[i])      if ((v=t1[i])!=fa)      {        if (!dfn[v])        {            dfs1(v,u);            low[u]=min(low[u],low[v]);        }        else low[u]=min(low[u],dfn[v]);      }    if (low[u]==dfn[u])    {        num++;        do        {            x=sta[top--];            bel[x]=num;        }        while (x!=u);    }}int dfs2(int u,int dis,int fa,int &p){    vis[u]=1;    int i,v,ret,tem1,tem2;    p=u;    ret=dis;    for (i=0;i<to[u].size();i++)      if ((v=to[u][i])!=fa)      {        tem1=dfs2(v,dis+1,u,tem2);        if (tem1>ret)        {            ret=tem1;            p=tem2;        }      }    return ret;}int main(){    int i,j,u,v,x,y,ans,tem;    scanf("%d%d",&n,&m);    for (i=1;i<=m;i++)    {        scanf("%d%d",&x,&y);        add(i*2,x,y);        add(i*2+1,y,x);    }    for (i=1;i<=n;i++)      if (!dfn[i])        dfs1(i,-1);    for (i=1;i<=n;i++)      for (j=f1[i];j;j=n1[j])        if (!have[u=bel[i]][v=bel[t1[j]]]&&u!=v)        {            have[u][v]=1;            to[u].push_back(v);        }    ans=n-1;    for (i=1;i<=num;i++)      if (!vis[i])      {        dfs2(i,1,-1,u);        tem=dfs2(u,1,-1,v);        if (tem!=1)          ans-=tem-3;      }    for (i=1;i<=num;i++)      if (to[i].size()==1)        ans--;    printf("%d\n",ans);}
0 0
原创粉丝点击