day2就藍題起步不是要我命嗎
目測資料:不都是基環樹和樹嘛?基環樹我不會但是這個樹的貪心不是裸的嗎?
大手一揮:這部分分我打定了!
int outp[
5100
],len;
void
dfs(
int x,
int fa)
void
main()
光榮地水到了60分
對於剩下的分,我們來好好觀察一下題面:
n
≤5000
n\le 5000
n≤5000
常數小的n
2logn
n^2\log n
n2logn
都可以過啊!
容 易 證 明整棵基環樹的環中一定會有一條邊是不需要走過的
博主只記了結論所以以後再來填坑啦
所以我們通過刪邊可以把基環樹轉化為一棵樹,然後直接跑第一種做法
首先我們要找出這個環
通過拓撲排序解決
首先,由於是雙向連通圖,所以每個點的入度至少為1
我們就從入度為1的點開始,進行寬搜
觀察一下樣例:
可以看到,3和4這兩個「環的入口」度數都為3
所以,任意乙個點觸碰到環上的點時,都無法將環上的點入度減為1
最後,我們就可以將這些入度不為零的點計入環中。
拓撲排序:
void
topsort()
}
還真就音譯topsort唄
主函式中部分:
topsort()
;for
(int i=
1;i<=n;i++
) on_cycle[i]
=in_degree[i]
>
1;
然後,我們就按照這些點排出環上的邊:
for
(int i=
1;i<=n;i++)if
(on_cycle[i]
)
get_edges
:
bool
get_edges
(int x,
int ed,
int fa)
}
然後就一根一根地斷,將cut
標記置為1
不要忘記雙向邊
for
(int i=
1;i<=cycle_len;i++
)
dfs
:
void
dfs(
int x,
int fa)
comp
:
bool
comp
(int a,
int b)
(本來為了省掉comp
用了basic_string
,結果被其他地方的re莫名勸退了)
最後outp
陣列就是答案了
**:
#include
#include
#include
#include
#include
using
namespace std;
inline
void
read
(int
&x)int n,m;
struct edge
a[11000];
int last[
5100
],len;
int in_degree[
5100];
inline
void
ins(
int x,
int y)
; last[x]
=len;
in_degree[y]++;
}int outp[
5100];
namespace solve1
void
main()
};namespace solve2
}bool
get_edges
(int x,
int ed,
int fa)
}void
dfs(
int x,
int fa)
bool
comp
(int a,
int b)
void
main()
for(
int i=
1;i<=cycle_len;i++
)for
(int i=
1;i<=n;i++
)printf
("%d "
,outp[i]);
}};int
main()
if(n==m)
solve2::
main()
;else solve1::
main()
;return0;
}
洛谷 P5022 旅行
傳送門 給出乙個有n nn個點的圖,一共有m mm雙向邊,求如何走能使得走到的點按先後順序字典序最小 對於前60 60 60 的資料來說,直接暴力dfs dfsdf s即可而其他的點,則根據基環樹的性質,將每條邊列舉刪去,剩下的肯定是棵樹 進而就得到了類似於60 60 60 的資料的情況 inclu...
洛谷P5049 洛谷P5022 題解 旅行
原題 資料加強版 加強版 參考你谷題解 終於調過了 又是一如既往的申必錯誤 noi plus石錘了 原題的資料允許我們 o n 2 暴力斷邊,但是加強版的資料達到了 n log n 級別,我們必須在斷邊這一環節尋求更好的解法。考慮我們進入環後在何處回溯 根據繼續走環走到的點分類 設當前已經從 b 走...
洛谷 P5022 旅行(DFS 斷環)
首先對於m n 1的情況非常好想 即這是一棵樹,然後從1節點開始,搜一遍。注意要搜出來的序列的字典序最小,所以用鄰接矩陣來儲存,存的時候按當前節點能到的節點的編號從小到大排序。當m n的時候 這時候便是乙個基環樹,在樹上的某乙個地方會有乙個環,會發現環上的有一條邊是不會走的。然而並不確定這條邊到底是...