首页 > 其他分享 >[NOIP2018] 旅行 题解

[NOIP2018] 旅行 题解

时间:2024-04-14 09:22:40浏览次数:29  
标签:原图 旅行 int 题解 复杂度 long NOIP2018 ans

明显要以 \(1\) 为起点。

原图是树

这种情况下,走路不能回头,只能用 \(dfs\) 的思路走。当然肯定每次都走较小的那棵子树,\(vector\) 存图后排序即可达到这种效果。

时间复杂度 \(O(n\log m)\)。

原图是基环树

明显可以分别考虑将所有边断掉后的情况,取字典序最小的。

时间复杂度 \(O(nm)\)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5005;
int n,m,vis[N],u[N],v[N];
int k,c,d,ans[N],b[N],f;
vector<int>g[N];
void dfs(int x){
    b[++k]=x;
    if(ans[k]>b[k]) f=1;
    if(ans[k]<b[k]&&!f){
        f=-1;
        return;
    }
    vis[x]=1;
    for(int i=0;i<g[x].size();i++){
        int y=g[x][i];
        if(x==c&&y==d) continue;
        if(x==d&&y==c) continue;
        if(!vis[y]) dfs(y);
        if(f==-1) return;
    }
}int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>u[i]>>v[i];
        g[u[i]].push_back(v[i]);
        g[v[i]].push_back(u[i]);
    }for(int i=1;i<=n;i++)
        sort(g[i].begin(),g[i].end());
    memset(ans,0x3f,sizeof(ans));
    if(m==n-1){
        dfs(1);
        for(int i=1;i<=k;i++)
            cout<<b[i]<<" ";
        return 0;
    }for(int i=1;i<=m;i++){
        memset(vis,0,sizeof(vis));
        memset(b,0x3f,sizeof(b));
        f=k=0;c=u[i];d=v[i];
        dfs(1);if(k<n) continue;
        for(int j=1;j<=n;j++)
            ans[j]=b[j];
    }for(int j=1;j<=n;j++)
        cout<<ans[j]<<" ";
    return 0;
}

标签:原图,旅行,int,题解,复杂度,long,NOIP2018,ans
From: https://www.cnblogs.com/chang-an-22-lyh/p/18133757

相关文章

  • CF382B Number Busters 题解
    总共就两种情况。当\(b\geqx\)时,\(b\)要减\(x\),\(c\)要减去一。当\(b\ltx\)时,\(a\)和\(c\)都要减一,\(b=w-x\)。如果\(c>a\),退出循环。每一次循环判断\(b\)跟\(x\)的关系,然后秒数加一。代码:#include<bits/stdc++.h>usingnamespacestd;inta,b,c,w,x;in......
  • CF455C Civilization 题解
    思路求树的直径,并存在一个数组里。用并查集来动态合并加维护区域信息(包括同一颗树里的有着相同祖先的点的合并,不同树之间的合并)。假设\(length\)数组:对于每棵树的根节点\(x\),\(length_{x}=\)该树的直径长度接下来对于每个询问(如果给出的两点在同一颗树内则忽略),利用并查......
  • [题解]SP10606 Balanced Numbers
    SP10606BalancedNumbers关于优化方式的说明详见数位dp例题及详解-下。SPOJ注册不上所以暂时无法提交w,但是3份代码与正解对拍没有问题。使用\(vis[0\sim9]\)表示\(0\sim9\)的访问情况,\(sta[0\sim9]\)表示\(0\sim9\)填写个数的奇偶性(奇数为\(1\),偶数为\(0\))。暴搜先打出来,......
  • 第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组题解
    试题A:握手问题本题总分:\(5\)分思路:组合计数,用为\(50\)个人握手的总方案数\(C^{2}_{50}\),减去七个人彼此没有握手握手的方案数\(C^{2}_{7}\)即为答案。A:握手问题#include<bits/stdc++.h>#defineintlonglong#definedblongdouble#defineall(f)f.begin()......
  • CF1923B Monsters Attack! 题解
    题目简述数轴上有$n$个怪兽。最初第$i$个怪兽在$x_i$位置上,且血量为$a_i$。你在位置$0$上。在每秒钟会发生:你给任意怪兽发射总共$k$颗子弹,受到攻击的怪兽血量减一。血量小于等于$0$的怪兽死亡。没有死亡的怪兽向你移动一个单位。当一个怪兽来到你的位置,你就输......
  • CF1165E Two Arrays and Sum of Functions 题解
    题目简述已知两个长度均为$n$的数组$a$和$b$。给定一个函数:$f(l,r)=\sum\limits_{l\lei\ler}a_i\cdotb_i$。你的任务是对数组$b$中的元素以任意的顺序重新排序,使$\sum\limits_{1\lel\ler\len}f(l,r)$的值最小。题目分析我们首先进行化简,发现题......
  • CF107A Dorm Water Supply 题解
    题目简述给出一个$n$个点,$m$条边的有向图,边带权。保证每个点的出度和入度最多为$1$。对于每一个入度为$0$,出度为$1$的点,我们在该点建一个水箱。对于每一个入度为$1$,出度为$0$的点,我们在该点建一个水龙头。可以发现,每一个水箱对应一个唯一的水龙头,我们将每对对应......
  • CF1942B Bessie and MEX 题解
    题目简述给定一个长度为$n$的数组$a$,让你构造一个等长的排列$p$,其中从$0$到$n-1$的每个整数恰好出现一次。满足对于每一个位置$a_i=\texttt{MEX}(p_1,p_2,\ldots,p_i)-p_i$,其中数组的$\texttt{MEX}$是不在该数组中出现的最小非负整数。题目分析我们发现正着做并......
  • CF244B Undoubtedly Lucky Numbers 题解
    题目简述给定一个$n$,问有多少个小于等于$n$的数只由两个不同的数字$x$和$y$组成。题目分析直接枚举肯定不行,我们考虑枚举$x$和$y$,再利用深搜,生成所有不大于$n$且只由$x$和$y$组成的数字,利用map去重,统计答案即可。代码#include<iostream>#include<map>usi......
  • 2023CCPC题解
    2023年第五届河南省CCPC大学生程序设计竞赛ProblemA.小水獭游河南#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){stringa;cin>>a;intst[27],ji=0;memset(st,0,sizeof(......