日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Noip2018]旅行

發布時間:2025/3/15 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Noip2018]旅行 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

小 Y 是一個愛好旅行的 OIer。她來到 X 國,打算將各個城市都玩一遍。

小Y了解到, X國的 n個城市之間有 m條雙向道路。每條雙向道路連接兩個城市。 不存在兩條連接同一對城市的道路,也不存在一條連接一個城市和它本身的道路。并且, 從任意一個城市出發,通過這些道路都可以到達任意一個其他城市。小 Y 只能通過這些 道路從一個城市前往另一個城市。

小 Y 的旅行方案是這樣的:任意選定一個城市作為起點,然后從起點開始,每次可 以選擇一條與當前城市相連的道路,走向一個沒有去過的城市,或者沿著第一次訪問該 城市時經過的道路后退到上一個城市。當小 Y 回到起點時,她可以選擇結束這次旅行或 繼續旅行。需要注意的是,小 Y 要求在旅行方案中,每個城市都被訪問到。

為了讓自己的旅行更有意義,小 Y 決定在每到達一個新的城市(包括起點)時,將 它的編號記錄下來。她知道這樣會形成一個長度為 n的序列。她希望這個序列的字典序 最小,你能幫幫她嗎? 對于兩個長度均為 n的序列 A和 B,當且僅當存在一個正整數 x,滿足以下條件時, 我們說序列 A的字典序小于 B。

對于任意正整數 1 ≤ i < x,序列 A的第 i個元素 A_i和序列 B的第 i個元素 B_i相同。

序列 A的第 x個元素的值小于序列 B的第 x個元素的值。

輸入格式

輸入文件共 m + 1行。第一行包含兩個整數 n,m(m ≤ n),中間用一個空格分隔。

接下來 m 行,每行包含兩個整數 u,v (1 ≤ u,v ≤ n),表示編號為 u和 v的城市之 間有一條道路,兩個整數之間用一個空格分隔。

輸出格式

輸出文件包含一行,n個整數,表示字典序最小的序列。相鄰兩個整數之間用一個 空格分隔。


首先貪心思路很容易想。

假設當前可以走到u,v兩個點,其中u的字典序小于v的字典序,我們顯然應該直接走u。因為如果走了v,那么之后再怎么走也走不出比走u字典序更小的路徑了。可以從兩個點拓展到更多的點。

所以總結一下,我們的貪心策略就是——走當前點連出去的字典序最小的點。

那么你前15組數據穩穩地過了。但后面的就有點不一樣——基環樹!那這個基環樹就把問題搞得復雜了。

根據題意,我們在走到環上時,我們可以往左走或者往右走。根據我們的貪心策略,我們往字典序小的一邊走。這里假設我們往左走。但是題目中說了,我們是可以往回走的,這個條件在基環樹上回發生什么化學反應呢?顯然,我們往左走了若干個點后,我們發現這個字典序還是挺大的,這時我們可以后悔一次!然后退回環的起始點,往右走,從而得到更優的解。那么例子也是很好舉的,樣例2就有一個:

Sample in6 6 1 3 2 3 2 5 3 4 4 5 4 6 Sample out1 3 2 4 5 6

這種后悔的操作可以怎么理解呢?首先你面前有一個環上的點,你本來要走過去,但是你沒走。這可以理解為把你和你面前的點之間的邊斷掉了。所以我們的核心思路就是——斷邊。我們可以先找出環,然后枚舉環上的每條邊,把它斷掉,然后根據前60分的貪心思路跑一遍。重復跑了若干次后,我們去最優解即可。時間復雜度O(N^2),再一看數據,加點小小的常數優化(代碼中標出)是可以過的。

#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<map> #define maxn 5001 using namespace std;vector<int> to[maxn]; int dfn[maxn],fa[maxn],tot,s; bool inloop[maxn]; pair<int,int> del1,del2; int n,m; int ans[maxn],path[maxn],d; map<pair<int,int>,bool> use;inline int read(){register int x(0),f(1); register char c(getchar());while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f; }//基環樹的情況 void dfs_getloop(int u){dfn[u]=++tot;for(register int i=0;i<to[u].size();i++){int v=to[u][i];if(!dfn[v]) fa[v]=u,dfs_getloop(v);else if(dfn[u]<dfn[v]){inloop[v]=true;do{ inloop[fa[v]]=true,v=fa[v]; }while(v!=u);}} } void dfs(int u,int pre){path[++d]=u;if(inloop[u]&&!s) s=u;for(register int i=0;i<to[u].size();i++){int v=to[u][i];if(v==pre||v==s) continue;if(make_pair(u,v)==del1||make_pair(u,v)==del2) continue;dfs(v,u);} } inline void cmp(){//比較答案for(register int i=1;i<=n;i++){if(path[i]<ans[i]) break;if(path[i]>ans[i]) return;}for(register int i=1;i<=n;i++) ans[i]=path[i]; }//樹的情況 void dfs2(int u,int pre){ans[++d]=u;for(register int i=0;i<to[u].size();i++){int v=to[u][i];if(v==pre) continue;dfs2(v,u);} }int main(){n=read(),m=read();for(register int i=1;i<=m;i++){int u=read(),v=read();to[u].push_back(v),to[v].push_back(u);}//按字典序排序,實際上這里用基排可以做到O(N)for(register int i=1;i<=n;i++) sort(to[i].begin(),to[i].end());if(m==n){dfs_getloop(1);memset(ans,0x3f,sizeof ans);for(register int i=1;i<=n;i++) if(inloop[i]){for(register int j=0;j<to[i].size();j++){int v=to[i][j];if(inloop[v]&&!use[make_pair(i,v)]){d=s=0,del1=make_pair(i,v),del2=make_pair(v,i);//斷掉雙向邊use[make_pair(i,v)]=true,use[make_pair(v,i)]=true;//這里用map記一下可以把我們的遍歷次數減半dfs(1,0),cmp();}}}}else dfs2(1,0);for(register int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");return 0; }

顯然我們的做法太暴力了,然后有人做了個這道題的加強版數據,n≤500000。經過分析和打表發現,我們所有刪邊的操作中好像也就只有那一次可以得到正解,所以我們要想辦法得到這條邊。

我們回想一下我們刪邊的原因:退回去換一個方向走的答案比繼續往下走更優。這里我們注意到,我們退回去時并不是直接退回到環的起始點,而是在往回走的每個點上把沒走過的地方走完了才繼續往回走。而走沒走過的地方顯然也需要遵循我們的貪心策略。那么什么時候往回走會更優呢?假設我們最近的一個還有地方沒走的祖先是u,它的沒走過的字典序最小的兒子為son(u),當前點為v,當前點的下一個在環上的點為son(v),那么顯然只有當son(u)<son(v)時往回走會更優——參照貪心的思路。所以我們只需要記下這個u即可。

不過我們還有需要注意的地方:

我們走的時候只能后悔一次。

只有當當前點的其它兒子都走過了時才可以選擇后悔。

時間復雜度為O(NlogN)。但由于本人寫法的原因(給兒子排序的部分),本人代碼的實際復雜度其實是

\[ O(N*\sum_{i=1}^{N}log_{2}Degree[i]) \]

可以發現增長率是很大的,但它確實是nlogn級別。不過在luogu開了O2可以過。

*degree表示這個點的度數

#include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> #define maxn 500001 using namespace std;vector<int> to[maxn]; int dfn[maxn],fa[maxn],tot; bool inloop[maxn],vis[maxn],flag; int n,m; int ans[maxn],d;inline int read(){register int x(0),f(1); register char c(getchar());while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f; }void dfs_getloop(int u){dfn[u]=++tot;for(register int i=0;i<to[u].size();i++){int v=to[u][i];if(!dfn[v]) fa[v]=u,dfs_getloop(v);else if(dfn[u]<dfn[v]){inloop[v]=true;do{ inloop[fa[v]]=true,v=fa[v]; }while(v!=u);}} }void dfs(int u,int fa,int pre){if(vis[u]) return;ans[++d]=u,vis[u]=true;priority_queue< int,vector<int>,greater<int> > q;for(register int i=0;i<to[u].size();i++) if(!vis[to[u][i]]||to[u][i]!=fa) q.push(to[u][i]);//換成這種寫法的原因是為了更好地判斷環上的下一個點不是自己的父親while(q.size()){int v=q.top(); q.pop();if(inloop[v]&&v>pre&&!q.size()&&!flag){ flag=true; return; }if(inloop[v]&&q.size()) dfs(v,u,q.top());else dfs(v,u,pre);} }int main(){n=read(),m=read();for(register int i=1;i<=m;i++){int u=read(),v=read();to[u].push_back(v),to[v].push_back(u);}if(m==n) dfs_getloop(1);dfs(1,0,0x3f3f3f3f);for(register int i=1;i<=n;i++){if(i!=1) putchar(' ');printf("%d",ans[i]);}return 0; }

轉載于:https://www.cnblogs.com/akura/p/10939812.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的[Noip2018]旅行的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲 欧美 自拍偷拍 | 国产欧美亚洲一区 | 国产黄色大片视频 | 国产欧美精品一区二区色综合 | 亚洲欧美精品久久 | 午夜精品福利一区二区蜜股av | 成人在线综合 | 娇妻玩4p被三个男人伺候电影 | 综合国产在线 | 自拍毛片| 欧美日韩国产中文 | 人人看人人爱 | 九九视频免费 | 岛国精品在线播放 | 中文字幕最新在线 | 亚洲午夜精品在线 | 永久免费看片 | 成人性视频网站 | 成人久久久久久久 | 蜜桃无码一区二区三区 | 色香蕉在线 | 天天色综合av | 黄色在线免费观看网站 | 日韩人妻一区二区三区蜜桃视频 | 国产精品极品白嫩在线 | 特大黑人巨人吊xxxx | 最新黄色av | 韩日精品在线观看 | 色图视频 | 亚洲老女人 | 大桥未久av一区二区三区中文 | 8x8ⅹ8成人免费视频观看 | 日本久久视频 | 国产15页| 93久久精品日日躁夜夜躁欧美 | 潘金莲性xxxxhd | 超碰caoprom | 成人免费视频大全 | 久久久久久久久久影视 | 日韩在线免费视频 | 日本a视频在线观看 | 欧美一区二区三区婷婷 | 国产精品一区二区网站 | 欧美bdsm调教视频 | 小罗莉极品一线天在线 | 久久久久玖玖 | 久草五月天| 天天综合天天添夜夜添狠狠添 | 91chinese在线| 蜜臀久久99精品久久久画质超高清 | 色操插| 国产精品国产三级国产aⅴ原创 | 自拍偷拍色 | 国产乱淫精品一区二区三区毛片 | 国产三级在线播放 | 2018中文字幕在线观看 | 青草视频在线免费观看 | 被黑人啪到哭的番号922在线 | 成人免费视频播放 | 日本人妻丰满熟妇久久久久久 | 九一亚洲精品 | 国产69视频在线观看 | 亚洲免费毛片 | 国产高清视频免费 | 37p粉嫩大胆色噜噜噜 | 天堂中文在线官网 | 欧美丝袜视频 | 免费黄色国产视频 | 乱老熟女一区二区三区 | 亚洲综合日韩 | 男女啪动最猛动态图 | 天天色综 | 青青青国产精品一区二区 | 亚洲欧美成人综合 | 国产一区二区网址 | 久草视频在线资源 | www.av88| 自拍三区| 国产精品电影一区 | 加勒比不卡视频 | 清冷学长被爆c躁到高潮失禁 | 一级黄色特级片 | 国产嫩草在线观看 | 国产在线观看中文字幕 | 在线观看不卡一区 | 欧美蜜臀| 日日躁夜夜躁aaaabbbb | 日韩av不卡一区 | 啪啪影音 | 色网综合 | 97se.com | 欧美在线性 | 日本中文字幕在线 | 国产aaaaa毛片 | 天堂中文在线免费观看 | 2022av视频 | 亚洲国产免费 | 麻豆精品| 欧美a级成人淫片免费看 |