码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 732F Tourist Reform

时间:2017-02-08 18:44:26      阅读:293      评论:0      收藏:0      [点我收藏+]

标签:dfs   add   pen   cloc   break   bre   div   string   cti   

边双连通分量。

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

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

接下来就是要去寻找强连通分量。对于一个无向图来说,每一个边-双联通分量都可以将每条边定向之后构造成一个强连通分量,$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\n",mx);
    for(int i=1;i<=sz;i++)
        if(gg[i]) printf("%d %d\n",V[i],U[i]);

    return 0;
}

 

CodeForces 732F Tourist Reform

标签:dfs   add   pen   cloc   break   bre   div   string   cti   

原文地址:http://www.cnblogs.com/zufezzt/p/6379078.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!