• 【洛谷P5049】旅行(数据加强版)


    题目链接

    m=n-1是直接按字典序dfs就行,

    m=n时是一棵基环树,我们发现当一个点在环上时,可以把它和它的一个在环上的儿子之间的边删掉,然后回溯,到达它的第一个有其他儿子的祖先的另一个儿子上,我们只需要记录一个点的第一个有其他儿子的祖先的其他儿子的最小值,贪心就行了

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    
    const int MAXN=500010;
    const int MAXM=1000010;
    
    inline int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0')x=(x<<3)+(x<<1)+c-'0',c=getchar();
        return x*f;
    }
    
    int n,m;
    int Head[MAXN],num;
    struct Edge{
        int x,to,next;
    }e[MAXM];
    inline void add(int x,int y){
        e[++num]=(Edge){x,y,Head[x]};Head[x]=num;
        e[++num]=(Edge){y,x,Head[y]};Head[y]=num;
    }
    
    int t[MAXM],cnt;
    void sortedge(){
        for(int i=1;i<=n;++i){
            cnt=0;
            for(int j=Head[i];j;j=e[j].next)
                t[++cnt]=e[j].to;
            sort(t+1,t+1+cnt);
            for(int k=Head[i],j=1;k;k=e[k].next,++j)
                e[k].to=t[j];
        }
    }
    
    int ans[MAXN],tot;
    bool vis[MAXN],onc[MAXN],flag=1;
    
    void dfs1(int x){
        ans[++tot]=x;vis[x]=1;
        for(int i=Head[x];i;i=e[i].next){
            int v=e[i].to;
            if(vis[v])continue;
            dfs1(v);
        }
    }
    
    int cym;
    int find(int x,int fa){
    	vis[x]=1;
    	for(int i=Head[x];i;i=e[i].next){
    		int v=e[i].to;
    		if(v==fa)continue;
    		if(vis[v]){
    			cym=v;
    			onc[v]=onc[x]=1;
    			return 1;
    		}
    		int t=find(v,x);
    		if(t==1){
    			onc[v]=onc[x]=1;
    			if(cym==x)return -1;
    			else return 1;
    		}
    		if(t==-1)return -1;
    	}
    	return 0;
    }
    
    inline int get_nxt(int i){
    	for(i=e[i].next;i;i=e[i].next)
    		if(!vis[e[i].to]) return e[i].to;
    	return -1;
    }
    
    void dfs2(int x,int fa,int mi){
    	if(vis[x]) return;
    	ans[++tot]=x; vis[x]=1;
    	for(int i=Head[x];i;i=e[i].next){
    		int v=e[i].to;
    		if(vis[v]) continue;
    		if(flag&&onc[v]&&v>mi&&get_nxt(i)==-1){
    			flag=0; return;
    		}
    		int nxt=get_nxt(i);
    		if(!onc[x]) nxt=-1;
    		dfs2(v,x,nxt==-1?mi:nxt);
    	}
    }
    
    void init(){
        n=read();m=read();
        int x,y;
        for(int i=1;i<=m;++i){
            x=read();y=read();
            add(x,y);
        }
        sortedge();
    }
    
    int main()
    {
        init();
        if(m==n-1) dfs1(1);
        else{
        	find(1,0);
        	memset(vis,0,sizeof(vis));
        	dfs2(1,0,0x3f3f3f3f);
    	}
    	for(int i=1;i<=n;++i)
    		printf("%d ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    线程 day40
    进程同步(multiprocess.Lock、multiprocess.Semaphore、multiprocess.Event) day38
    进程 day36
    操作系统的发展史 day36
    git项目.gitignore文件不生效解决办法
    Java8 Lambda表达式和流操作如何让你的代码变慢5倍
    @GetMapping和@PostMapping接收参数的格式
    Non-parseable POM C:Usersadmin.m2 epositoryorgspringframework问题解决方案
    hessian
    eclipse 中PlantUML的安装和使用
  • 原文地址:https://www.cnblogs.com/yjkhhh/p/11667711.html
Copyright © 2020-2023  润新知