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 }
  • 相关阅读:
    玛里苟斯[清华集训2014 Day1]
    bzoj3585 mex
    Luogu 3793 由乃救爷爷
    Luogu5221 Product
    bzoj1834 [ZJOI2010]network 网络扩容
    CF650C Table Compression
    bzoj3211 花神游历各国
    bzoj1066 [SCOI2007]蜥蜴
    hdu2121 Ice_cream's world II
    Luogu2792 [JSOI2008]小店购物
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6131084.html
Copyright © 2011-2022 走看看