导航

Codeforces 732F [边双联通分量][tarjan]

Posted on 2016-10-19 21:56  tun~  阅读(316)  评论(0编辑  收藏  举报
/*
不要低头,不要放弃,不要气馁,不要慌张
题意:
给一个无向图。现在要求给这个无向图的边加上方向。
定义f(x)为从x点出发能够到达的点的数目。
使得MIN(f(x))最大。

思路:
先tarjan找边双分量,然后从点数最大的边双分量开始dfs。
就酱。


中午老妈刚给我打电话问感冒没,我说没有,晚上就发烧了   gg
*/









#include<bits/stdc++.h>
#define N 400050
using namespace std;
int ednum;
struct edge{
    int nn;
    int id;
    edge *next;
};
edge edges[N<<1];
edge *adj[N];
struct st{
    st(){}
    st(int a,int b,int c){
        s=a;e=b;xu=c;
    }
    int s,e,xu;
};
vector<st>ans;
inline void addedge(int a,int b,int c){
    edge *tmp=&edges[ednum++];
    tmp->id=b;
    tmp->nn=c;
    tmp->next=adj[a];
    adj[a]=tmp;
}
int dfn[N],low[N],id[N],s[N],p,num,t,son[N],nnm[N];//dfn记录dfs时间戳
//low代表当前点到达的最小时间戳,id对点进行分组编号.num是时间戳
//s临时存储数据的手工栈,p栈顶元素的位置,son记录儿子因为无向图记录边都是两个边
void tarjan(int pos){
    dfn[pos]=low[pos]=++num;
    s[++p]=pos;
    for(edge *it=adj[pos];it;it=it->next){
        if(!dfn[it->id]){
            son[pos]=it->id;
            tarjan(it->id);
        }
        if(son[it->id]!=pos){
            low[pos]=min(low[pos],low[it->id]);
        }
    }
    if(low[pos]==dfn[pos]){
        t++;
        int y;
        do{
            nnm[t]++;
            y=s[p--];
            id[y]=t;
        }while(y!=pos);
    }
}
bool vis[N];
bool vvis[N];
void dfs(int pos){
    vis[pos]=1;
    for(edge *it=adj[pos];it;it=it->next){
        if(!vis[it->id]){
            son[pos]=it->id;
            dfs(it->id);
        }
        if(son[it->id]!=pos&&!vvis[it->nn]){
            vvis[it->nn]=1;
            ans.push_back(st(pos,it->id,it->nn));
        }
    }
}
bool cmp(st a,st b){
    return a.xu<b.xu;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b,i);
        addedge(b,a,i);
    }
    tarjan(1);
    int pos,nnn=-1;
    for(int i=1;i<=t;i++){
        if(nnn<nnm[i]){
            pos=i;
            nnn=nnm[i];
        }
    }
    printf("%d\n",nnn);
    for(int i=1;i<=n;i++){
        if(id[i]==pos){
            memset(vis,0,sizeof(vis));
            memset(son,0,sizeof(son));
            dfs(i);
            break;
        }
    }
    sort(ans.begin(),ans.end(),cmp);
    for(int i=0;i<ans.size();i++){
        printf("%d %d\n",ans[i].e,ans[i].s);
    }
}