noip 2018 day2 T1 旅行 基环树 tarjan

Code:

#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
void setIO(string a){
    freopen((a+".in").c_str(),"r",stdin);
    freopen((a+".out").c_str(),"w",stdout);
}

const int maxn = 5009;
int low[maxn], pre[maxn], idx[maxn], A[maxn], B[maxn], ab;
bool is[maxn][maxn];
vector<int>G[maxn], idxx[maxn];
stack<int>S;
int n,m,scc, num;
void addedge(int u,int v){ G[u].push_back(v); }
void tarjan(int u,int fa){
    low[u]=pre[u]=++scc;
    S.push(u);
    for(int i=0;i<G[u].size();++i){
        if(G[u][i]==fa) continue;
        if(!pre[G[u][i]]) {
            tarjan(G[u][i],u);
            low[u]=min(low[u],low[G[u][i]]);
        }
        else if(!idx[G[u][i]]) low[u]=min(low[u],pre[G[u][i]]); 
    }
    if(low[u]==pre[u])
    {
        ++num;
        for(;;){
            int g=S.top();S.pop();
            idxx[num].push_back(g);
            idx[g]=num;
            if(g==u) break;
        }
    }
}
int tag[maxn], arr[maxn][maxn], p, current;
void dfs(int u){
    arr[current][++p]=u;
    tag[u]=1;
    int siz=G[u].size();
    for(int i=0;i<siz;++i){
        if(tag[G[u][i]] || is[u][G[u][i]]) continue;
        dfs(G[u][i]);
    }
}
int main(){
    //setIO("travel");
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b);
        addedge(b,a);
    }
    for(int i=1;i<=n;++i){
        int siz=G[i].size();
        sort(G[i].begin(),G[i].end());
    }
    tarjan(1,0);
    for(int i=1;i<=num;++i){
        if(idxx[i].size()>1) {
            int siz=idxx[i].size();
            for(int j=0;j<siz;++j)
                for(int k=j+1;k<siz;++k) A[++ab]=idxx[i][j],B[ab]=idxx[i][k];
            break;
        }
    }
    if(ab==0) { dfs(1); for(int i=1;i<=n;++i) printf("%d ",arr[0][i]); return 0;}
    for(int i=1;i<=ab;++i){
        p=0;
        ++current;
        memset(tag,0,sizeof(tag));
        is[A[i]][B[i]]=is[B[i]][A[i]]=1;
        dfs(1);
        is[A[i]][B[i]]=is[B[i]][A[i]]=0;
    }
    int cur_best=1;
    for(int i=2;i<=current;++i){
        for(int j=1;j<=n;++j) if(arr[cur_best][j]!=arr[i][j]){
             if(arr[cur_best][j]>arr[i][j]) cur_best=i;
             break;
        }
    }
    for(int i=1;i<=n;++i) printf("%d ",arr[cur_best][i]);
    printf("\n");
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/9973150.html