zoukankan      html  css  js  c++  java
  • 洛谷 P5022 旅行(DFS+断环)

    题目链接:https://www.luogu.com.cn/problem/P5022

    首先对于m=n-1的情况非常好想:即这是一棵树,然后从1节点开始,搜一遍。注意要搜出来的序列的字典序最小,所以用邻接矩阵来存储,存的时候按当前节点能到的节点的编号从小到大排序。

    当m=n的时候:这时候便是一个基环树,在树上的某一个地方会有一个环,会发现环上的有一条边是不会走的。然而并不确定这条边到底是哪一条,所以进行枚举断环。但找出环来太麻烦,所以可以直接枚举m条边中哪一条边不会走,每次看能否将n个点都走一遍,即cnt是否等于n。如果都能走,则每次更新字典序最小的ans。

    关于将一条边断掉:不需要考虑复杂,只需要假设断掉的边的两个端点分别为x,y,在DFS时,如果当前的边的端点恰好是x,y,则直接continue即可。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=5010;
     8 vector<int> a[N];
     9 int cnt,tot,x,y,n,m;
    10 struct node{
    11     int to,from,next;
    12 }edge[N<<1];
    13 int head[N],k[N],ans[N],vis[N];
    14 void add(int u,int v){
    15     edge[tot].to=v;
    16     edge[tot].from=u;
    17     edge[tot].next=head[u];
    18     head[u]=tot++;
    19 }
    20 void change(){
    21     for(int i=1;i<=n;i++) ans[i]=k[i];
    22 }
    23 bool check(){
    24     for(int i=1;i<=n;i++){
    25         if(k[i]<ans[i]) return 1;
    26         else if(k[i]>ans[i]) return 0;
    27         else continue;
    28     }
    29 }
    30 void work(int u,int fa){
    31     if(vis[u]) return;
    32     vis[u]=1;
    33     ans[++cnt]=u;
    34     for(int i=0;i<a[u].size();i++){
    35         int v=a[u][i];
    36         if(v==fa) continue;
    37         work(v,u);
    38     }
    39 }
    40 void DFS(int u,int fa){
    41     if(vis[u]) return;
    42     vis[u]=1;
    43     k[++cnt]=u;
    44     for(int i=0;i<a[u].size();i++){
    45         int v=a[u][i];
    46         if(v==fa) continue;
    47         if((v==x&&u==y)||(v==y&&u==x)) continue;
    48         DFS(v,u);
    49     }
    50 }
    51 int main(){
    52     memset(head,-1,sizeof(head));
    53     scanf("%d%d",&n,&m);
    54     for(int i=1;i<=m;i++){
    55         int u,v;
    56         scanf("%d%d",&u,&v);
    57         a[u].push_back(v); a[v].push_back(u);
    58         add(u,v); add(v,u);
    59     }
    60     for(int i=1;i<=n;i++) sort(a[i].begin(),a[i].end());
    61     if(n==m){
    62         for(int i=0;i<tot;i+=2){
    63             cnt=0; x=edge[i].from; y=edge[i].to;
    64             memset(vis,0,sizeof(vis));
    65             DFS(1,-1);
    66             if(cnt<n) continue;
    67             if(ans[1]==0) change();
    68             else if(check()) change();
    69         }
    70         for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    71         return 0;
    72     }
    73     work(1,-1);
    74     for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    75     return 0;
    76 }
    AC代码
  • 相关阅读:
    idea设置全局ignore
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistributable. Please ins
    win 2012 安装mysql 5.7.20 及报错 This application requires Visual Studio 2013 Redistr
    kafka 删除 topic
    java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError
    Centos中使用yum安装java时,没有jps的问题的解决
    Spring 整合Junit
    Spring纯注解配置
    Spring 基于注解的 IOC 配置
    打印java系统的信息
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13832694.html
Copyright © 2011-2022 走看看