zoukankan      html  css  js  c++  java
  • CodeForces 51F Caterpillar

    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飞

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 #include<vector>
      7 using namespace std;
      8 const int mx[5]={0,1,0,-1,0};
      9 const int my[5]={0,0,1,0,-1};
     10 const int mxn=2100;
     11 int read(){
     12     int x=0,f=1;char ch=getchar();
     13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     15     return x*f;
     16 }
     17 struct edge{
     18     int v,nxt;
     19 }e[200010];
     20 int hd[mxn],mct=0;
     21 void add_edge(int u,int v){
     22     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
     23 }
     24 int mp[mxn][mxn];
     25 int n,m;
     26 int dtime=0;
     27 int low[mxn],dfn[mxn];
     28 int belone[mxn],cnt;
     29 int st[mxn],top=0;
     30 void tarjan(int u,int fa){
     31     dfn[u]=low[u]=++dtime;
     32     st[++top]=u;
     33     for(int i=hd[u];i;i=e[i].nxt){
     34         int v=e[i].v;
     35         if(v==fa)continue;
     36         if(!dfn[v]){
     37             tarjan(v,u);
     38             low[u]=min(low[u],low[v]);
     39         }
     40         else low[u]=min(low[u],dfn[v]);
     41     }
     42     if(dfn[u]==low[u]){
     43         cnt++;
     44         int v=0;
     45         do{
     46             v=st[top--];
     47             belone[v]=cnt;
     48         }while(v!=u);
     49     }
     50     return;
     51 }
     52 vector<int>eg[mxn];
     53 int dis[mxn];
     54 bool vis[mxn];int kct=0;
     55 int tg=0;
     56 void DFS(int u,int fa){
     57     vis[u]=1;
     58     dis[u]=dis[fa]+1;
     59     if(dis[u]>dis[tg])tg=u;
     60     for(int i=0;i<eg[u].size();i++){
     61         int v=eg[u][i];
     62         if(v==fa)continue;
     63         DFS(v,u);
     64     }
     65     return;
     66 }
     67 int pos1,pos2;
     68 int outd[mxn];
     69 int solve(){
     70     if(cnt==1)return n-1;
     71     int i,j;
     72     for(i=1;i<=n;i++){
     73         for(j=hd[i];j;j=e[j].nxt){
     74             int v=e[j].v;
     75             if(mp[belone[i]][belone[v]])continue;
     76             if(belone[i]!=belone[v]){
     77                 eg[belone[i]].push_back(belone[v]);
     78                 mp[belone[i]][belone[v]]=1;//防止加重边 
     79                 outd[belone[i]]++;
     80             }
     81         }
     82     }
     83     int res=0;
     84     for(i=1;i<=cnt;i++)if(outd[i]==1) res++;//叶子节点数
     85     for(i=1;i<=cnt;i++){
     86         if(vis[i])continue;
     87         kct++;//联通块计数 
     88         //
     89         tg=0;
     90         DFS(i,0);
     91         pos1=tg;
     92         tg=0;
     93         DFS(pos1,0);
     94         pos2=tg;
     95         //求直径 
     96         if(dis[pos2]<2)res++;
     97         else res+=dis[pos2]-2;
     98     }
     99     return n-res+kct-1;
    100 }
    101 int main()
    102 {
    103     n=read();m=read();
    104     int i,j,u,v;
    105     for(i=1;i<=m;i++){
    106         u=read();v=read();
    107         add_edge(u,v);
    108         add_edge(v,u);
    109     }
    110     for(i=1;i<=n;i++)
    111         if(!dfn[i])tarjan(i,0);
    112     int ans=solve();
    113     printf("%d
    ",ans);
    114     return 0;
    115 }
  • 相关阅读:
    【备忘录】Sublime Text编辑器如何在选中的多行行首增加字符串
    微信卡券领取页面提示签名错误,微信卡券JSAPI签名校验工具对比签名一模一样,cardExt扩展字段有问题
    程序运行时动态生成缓存时存在的问题
    golang的beego框架开发时出现的问题纪录
    【备忘录】CentOS服务器mysql忘记root密码恢复
    试玩swoole扩展 第一天
    spring 定时任务执行2次
    JVM CUP占用率过高排除方法,windows环境
    spring cloud 服务A调用服务B自定义token消失,记录
    java.sql.SQLException: Value '0000-00-00' can not be represented as java.sql.Timestamp
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6131084.html
Copyright © 2011-2022 走看看