• CodeForces 732F Tourist Reform


    边双连通分量。

    这题有一点构造的味道。一个有向图,经过强连通缩点之后会形成一个有向无环图。

    如果将最大的强连通分量放在顶端,其余的强连通分量都直接或间接指向他,那么这样就构造出了符合要求的图。

    接下来就是要去寻找强连通分量。对于一个无向图来说,每一个边-双联通分量都可以将每条边定向之后构造成一个强连通分量,$dfs$一遍即可。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-10;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    const int maxn = 800000 + 5;
    int n,m;
    
    int pre[maxn], dfs_clock, bcc_cnt;
    vector<int>G[maxn], bcc[maxn];
    
    int belong[maxn],U[maxn],V[maxn],sz;
    int flag[maxn],ff[maxn],gg[maxn],ge[maxn],dd[maxn];
    
    int Tarjan(int u,int fa)
    {
        int lowu=pre[u]=++dfs_clock;
    
        for(int i=0;i<G[u].size();i++)
        {
            int v=V[G[u][i]];
            if(!pre[v])
            {
                int lowv=Tarjan(v,u);
                lowu=min(lowu,lowv);
    
                if(lowv > pre[u]) ge[(G[u][i]+1)/2]=1;
            }
            else if(v!=fa) lowu=min(lowu,pre[v]);
        }
    
        return lowu;
    }
    
    void add(int a,int b)
    {
        sz++; U[sz]=a; V[sz]=b;
        G[a].push_back(sz);
    }
    
    void DFS(int x,int y)
    {
        flag[y]=1;
        for(int i=0;i<G[y].size();i++)
        {
            int v=V[G[y][i]];
            if(v==x) continue;
            if(ff[(G[y][i]+1)/2]==1) continue;
            ff[(G[y][i]+1)/2]=1;
            gg[G[y][i]]=1;
            if(flag[v]==0) DFS(y,v);
        }
    }
    
    void dfs(int x)
    {
        belong[x]=bcc_cnt;
        for(int i=0;i<G[x].size();i++)
        {
            if(ge[(G[x][i]+1)/2]==1) continue;
            int v=V[G[x][i]];
            if(belong[v]!=0) continue;
            dfs(v);
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int a,b; scanf("%d%d",&a,&b);
            add(a,b); add(b,a);
        }
    
        for (int i = 1; i <= n; i++) if (!pre[i]) Tarjan(i, -1);
    
        for(int i=1;i<=n;i++)
        {
            if(belong[i]!=0) continue;
            bcc_cnt++; dfs(i);
        }
    
        for(int i=1;i<=n;i++) dd[belong[i]]++;
    
        int mx=0,idx=0;
        for(int i=1;i<=bcc_cnt;i++) if(dd[i]>mx) mx=dd[i],idx=i;
    
        for(int i=1;i<=n;i++) if(belong[i]==idx) { DFS(-1,i); break; }
    
        printf("%d
    ",mx);
        for(int i=1;i<=sz;i++)
            if(gg[i]) printf("%d %d
    ",V[i],U[i]);
    
        return 0;
    }
  • 相关阅读:
    PC逆向之代码还原技术,第三讲汇编中加法的代码还原
    PC逆向之代码还原技术,第二讲寻找程序入口点
    C++STL模板库适配器之优先级队列
    C++STL模板库适配器之queue队列
    C++STL模板库适配器之stack容器
    iBinary C++STL模板库关联容器之map/multimap
    C++STL模板库关联容器之set/multiset
    C++STL模板库序列容器之deque
    C++STL模板库序列容器之List容器
    C++STL模板库序列容器之vector
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6379078.html
Copyright © 2020-2023  润新知