• Codeforces 1000E We Need More Bosses 【无向图缩点】【树的直径】


    世纪好题!

    无向图缩点的话 在dfs的时候禁止访问父节点就好了,其他与有向图缩点一样。

    然后就是求树的直径。

    画图想想就理解了,从“必经之路”入手,想到环是造成非必经之路的原因。我们缩完点后得到无环连通图,即一棵树,树上每两个点之间有一条唯一的路径,路径上每条边都是必经之路。

    所以只是到 tarjan缩点模板 + 树的直径模板!

     好题啊。。。

    prev是关键字,所以用的prevv

     1 #include<iostream>
     2 #include<vector>
     3 #include<map>
     4 #include<stack>
     5 #include<queue>
     6 #include<cstring>
     7 using namespace std;
     8 
     9 int m1[300005],m2[300005],prevv[300005],low[300005],instack[300005],time;
    10 vector<int> edge[300005],edge2[300005];
    11 map<int,int> scc;
    12 
    13 stack<int> s;
    14 void tarjan(int u,int last){
    15     prevv[u] = low[u] = ++time;
    16     //cout<<u<<" "<<time<<endl;
    17     s.push(u); instack[u]=1;
    18     for(int i=0;i<edge[u].size();i++){
    19         int v = edge[u][i];
    20     //    cout<<"``` "<<u<<" "<<v<<endl;
    21         if(v==last) continue;//无向图时禁止访问父结点 
    22         if( prevv[v]==0 ){
    23             tarjan(v,u);
    24             low[u] = min(low[u],low[v]);
    25         }
    26         else if( instack[v] ) low[u] = min(low[u],prevv[v]); 
    27     }
    28     
    29     if(prevv[u]==low[u]){
    30     //    cout<<"??? "<<s.top()<<" "<<u<<endl;
    31         while(s.top()!=u){
    32             int index=s.top(); s.pop(); scc[index]=u; instack[index]=0;
    33         }
    34         s.pop(); scc[u]=u; instack[u]=0;
    35     }
    36 }
    37 
    38 int d[300005];
    39 queue<pair<int,int> > q;
    40 void bfs(int s){
    41     memset(d,-1,sizeof(d));
    42     q.push( make_pair(s,0) );
    43     d[s]=0;
    44     while(!q.empty()){
    45         pair<int,int> p = q.front(); q.pop();
    46         int index=p.first,length=p.second;
    47         d[index]=length;
    48         for(int i=0;i<edge2[index].size();i++){
    49             int v=edge2[index][i];
    50             if(d[v]==-1) q.push(make_pair(v,length+1));//继续bfs 
    51         }
    52     }
    53 }
    54 
    55 int main(){
    56     int n,m; scanf("%d%d",&n,&m);
    57     for(int i=1;i<=m;i++){
    58         scanf("%d%d",&m1[i],&m2[i]);
    59         edge[m1[i]].push_back(m2[i]);
    60         edge[m2[i]].push_back(m1[i]);
    61     }
    62     
    63     tarjan(1,0);//无向图缩点 
    64 //    for(int i=1;i<=n;i++) cout<<"!!! "<<i<<" "<<scc[i]<<endl;
    65     
    66     for(int i=1;i<=m;i++){
    67         if( scc[ m1[i] ]==scc[ m2[i] ] ) continue;
    68         else{
    69             edge2[ scc[m1[i]] ].push_back( scc[m2[i]] );
    70             edge2[ scc[m2[i]] ].push_back( scc[m1[i]] );
    71         }
    72     }
    73 
    74     //树的直径
    75     bfs(1);
    76     int maxd=1;
    77     for(int i=2;i<=n;i++){
    78         if( d[i]>d[maxd] ) maxd=i;
    79     }
    80     bfs(maxd);
    81     
    82     int ans=d[1];
    83     for(int i=2;i<=n;i++){
    84         if( d[i]>ans ) ans=d[i];
    85     }
    86     cout<<ans;
    87     
    88     return 0;
    89 }
  • 相关阅读:
    八数码
    java swing打包为exe
    java swing 打为exe
    Intellij Idea开发: 手把手教你Java GUI开发,并且打包成可执行Jar程序
    HSSFworkbook,XSSFworkbook,SXSSFworkbook区别总结
    java poi修改EXCEL单元格的内容
    java 操作excel类型转换
    css截取过长文本,省略号显示
    idea swing 设置为utf8乱码
    Java使用POI读取和写入Excel指南
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/9281675.html
Copyright © 2020-2023  润新知