zoukankan      html  css  js  c++  java
  • Codeforces 732F [边双联通分量][tarjan]

    /*
    不要低头,不要放弃,不要气馁,不要慌张
    题意:
    给一个无向图。现在要求给这个无向图的边加上方向。
    定义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
    ",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
    ",ans[i].e,ans[i].s);
        }
    }
  • 相关阅读:
    busybox 注意事项
    Implicit vs Explicit Sharing
    Font Creator Program 字库修改合并软件
    Iperf 源代码分析(四)
    QML 中文支持
    file operation
    MFC异常 与C++标准异常
    统一建模语言(UML) 版本 2.0
    MultiByteToWideChar和WideCharToMultiByte用法详解
    UML 基础: 类图
  • 原文地址:https://www.cnblogs.com/tun117/p/5978888.html
Copyright © 2011-2022 走看看