zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 46 (Rated for Div. 2)E. We Need More Bosses

    题目链接:E. We Need More Bosses

    题解:tarjan有向图缩点之后求树的直径就是答案:应为在同一个强联通里的边就不是必须边,参考了这个

    #include<bits/stdc++.h>
    #include<set>
    #include<cstdio>
    #include<iomanip>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #define pb push_back
    #define mk make_pair
    #define ll long long
    #define fi first
    #define se second
    #define PI 3.14159265
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define eps 1e-7
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    typedef unsigned long long ull;
    const int mod=998244353;
    const ll inf=0x3f3f3f3f3f3f3f;
    const int maxn=1e6+5;
    using namespace std;
    int n,m;
    vector<int>g[maxn],G[maxn];
    int dnf[maxn],low[maxn],ind,scc[maxn],scc_cnt,s[maxn],head,d[maxn];
    void tarjan(int v,int f)
    {
        dnf[v]=low[v]=++ind;
        s[++head]=v;
        for(int to :g[v])
        {
            if(f==to)continue;
            if(!dnf[to])
            {
                tarjan(to,v);
                low[v]=min(low[v],low[to]);
            }
            else low[v]=min(low[v],dnf[to]);
        }
        if(low[v]==dnf[v])
        {
            scc[v]=++scc_cnt;
            while(s[head]!=v)scc[s[head--]]=scc_cnt;
            head--;
        }
    }
    void dfs(int v,int f,int dep)
    {
        d[v]=dep;
        for(int to:G[v])
        {
            if(to!=f)dfs(to,v,dep+1);
        }
    }
    int main()
    {
        /* ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);*/
        //cin>>n>>m;
        scanf("%d %d",&n,&m);
        //cout<<d[(int)1e9]<<endl;
        for(int i=0;i<m;i++)
        {
            int x,y;
            //cin>>x>>y;
            scanf("%d %d",&x,&y);
            g[x].pb(y);g[y].pb(x);
        }
        tarjan(1,0); //cout<<"SSS"<<endl;
        for(int i=1;i<=n;i++)
        {
            for(int to:g[i])
            {
                if(scc[i]!=scc[to])
                {
                    G[scc[i]].pb(scc[to]);
                }
            }
        }
        dfs(1,0,0);
        int tmp=0,s;
        for(int i=1;i<=scc_cnt;i++)
        {
            if(d[i]>tmp)s=i,tmp=d[i];
        }
        for(int i=0;i<=scc_cnt;i++)d[i]=0;
        dfs(s,0,0);
        int ans=0;
        for(int i=1;i<=scc_cnt;i++)
        {
            ans=max(d[i],ans);
        }
        printf("%d
    ",ans);
        return 0;
    }

    有个相似的题

    题目链接:E. Anton and Tree

    题意:就是一次操作选中一个点并把所有到这个点最短路经过是颜色相同的点颜色反转,问至少几次操作把所有的颜色变为相同的点

    题解:把相同颜色的相邻的点缩成一个点然后求树的直径,答案时(直径+1)/2

    #include<bits/stdc++.h>
    #include<set>
    #include<cstdio>
    #include<iomanip>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #define pb push_back
    #define mk make_pair
    #define ll long long
    #define fi first
    #define se second
    #define PI 3.14159265
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define eps 1e-7
    #define pii pair<int,int>
    #define pll pair<ll,ll>
    typedef unsigned long long ull;
    const int mod=998244353;
    const ll inf=0x3f3f3f3f3f3f3f;
    const int maxn=1e6+5;
    using namespace std;
    int n,m;
    vector<int>g[maxn],G[maxn];
    int c[maxn];
    int sc[maxn],cnt;
    int dis[maxn];
    bool vis[maxn];
    void dfs(int v,int f,int ind,int cm)
    {
        sc[v]=ind;
        vis[v]=true;
        for(int to:g[v])
        {
            if(to==f)continue;
            if(!vis[to]&&c[to]==cm)dfs(to,v,ind,cm);
        }
    }
    void dfs1(int v,int f,int d)
    {
        dis[v]=d;
        for(int to:G[v])
        {
            if(to==f)continue;
                dfs1(to,v,d+1);
        }
    }
    int main()
    {
         ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        cin>>n;
        for(int i=1;i<=n;i++)cin>>c[i];
        for(int i=0;i<n-1;i++)
        {
            int x,y;
            cin>>x>>y;
            g[x].pb(y);g[y].pb(x);
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]) dfs(i,0,++cnt,c[i]);
        }
        for(int i=1;i<=n;i++)
        {
            for(int to:g[i])
            {
                if(sc[to]!=sc[i])
                {
                    G[sc[i]].pb(sc[to]);
                }
            }
        }
        dfs1(1,0,0);int tmp=0,s;
        for(int i=1;i<=cnt;i++)
        {
            if(dis[i]>tmp)s=i,tmp=dis[i];
        }
        memset(dis,0,sizeof(dis));
        dfs1(s,0,0);
        int ans=0;
        for(int i=1;i<=cnt;i++)
        {
            ans=max(ans,dis[i]);
        }
        cout<<(ans+1)/2<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    poj2328简单模拟
    一个简单的Silverlight的DataBinding和DateTemplate的Demo
    poj3468线段树_区间数字统计
    一个Silverlight的可视化图的DataBinding的Demo
    poj3321 dfs+树状数组
    C#拖拽控件
    【存档归纳】Sqlserver数据库详解 深度挖掘sqlserver帮助所得 一
    电脑蓝屏原因分析利器
    C# B/S程序如何获取客户端的MAC地址
    尚需研究之QQ音乐首页的图片轮换
  • 原文地址:https://www.cnblogs.com/lhclqslove/p/9295804.html
Copyright © 2011-2022 走看看