搜尋 隨機化貪心 NOI2006 聰明的導遊

2021-06-06 21:37:53 字數 3045 閱讀 6714

題目描述:

【問題描述】

小佳最近迷上了導遊這個工作,一天到晚想著帶遊客參觀各處的景點。正好m 市在舉行 noi,來參觀的人特別的多。不少朋友給小佳介紹了需要導遊的人。

m 市有 n 個著名的景點,小佳將這些景點從 1 至 n 編號。有一些景點之間存在雙向的路。小佳可以讓遊客們在任何乙個景點集合,然後帶著他們參觀,最後也可以在任何乙個景點結束參觀。不過,來參觀的遊客們都不願去已經參觀過的地方。所以,小佳不能帶遊客們經過同乙個景點兩次或兩次以上。

小佳希望你幫助他設計乙個方案, 走可行的路線, 帶遊客們參觀盡可能多的地方。

【輸入格式】

輸入檔案為 guide1.in~guide10.in,第一行為兩個整數 n,m,分別表示景點數和路的條數。接下來 m 行,每行兩個整數 a,b,表示景點 a 和景點 b 之間有一條雙向路。

【輸出格式】

你需要將答案輸出到 guide1.out~guide10.out 中,guide?.out 為對應 guide?.in的答案。輸出的第一行為 p,表示你能找到的路徑所經過的景點個數。接下來 p行,每行乙個整數,按順序表示你所找到的路徑上的每乙個景點。

【說明】

這是一道提交答案式的題目,你不需要提供任何源**,只需要將自己的輸出檔案放在與*.in 同乙個目錄即可。

【樣例】

樣例輸入

5 51 2

3 22 4

2 54 5

樣例輸出41

245【樣例說明】

題目可能有多解,該樣例有 4 個解,你只需輸出其中任何乙個解。

解1    解2    解3    解4

4    4    4    4

1    1    3    3

2    2    2    2

4    5    4    5

5    4    5    4

【評分方法】

你的評分將由你的答案與標準答案之間的差異來給定。設你的答案正確且參

觀的景點數為 x,我們所給出的結果為 ans,則按下表計算你的得分:

得分        條件            得分        條件

12            x > ans            5            x ≥ ans * 0.93

10            x = ans            4            x ≥ ans * 0.9

9            x ≥ ans – 1        3            x ≥ ans * 0.8

8            x ≥ ans – 2        2            x ≥ ans * 0.7

7            x ≥ ans – 3        1            x ≥ ans * 0.5

6            x ≥ ans * 0.95    0            x < ans * 0.5

如果有多項滿足,則取滿足條件中的最高得分。

第5、6組資料有規律,為若干個矩形網格拼接成的,找出其中最大的矩形然後按照規則構造即可。

第7組資料有規律,每5個為乙個連通塊,每兩個相鄰的連通塊之間有且只有一條邊相連(即1~5,6~10,11~15,...完全連通。且1~5中存在一點到6~10中的點有邊,

6~10中存在一點到11~15中的點有邊,依次類推),可以手動構造。

第9、10組資料為一棵樹,可以用兩次bfs解決。

總的做法:隨機起點,搜尋。期望得分:大於80分。

某一天突然右找了篇題解,發現可以用以下方法做:

受到第9、10組資料的啟發,我們可以在原圖的基礎上隨機生成一棵樹,然後在樹中找最長鏈作為最終答案。

在生成樹的時候,需要一點點技巧才能得到滿分。

注意到如果生成的樹中,出現了乙個度很大的結點,那麼答案必定不是最優的。

於是可以按照結點的度來進行貪心,每次先擴充套件度最小的結點,再擴充套件其它結點。

**:

/************************************\

* @prob: noi2006 guide *

* @auth: wang junji *

* @stat: 100分 *

* @date: june. 5th, 2012 *

* @memo: 隨機化貪心,樹上求最長鏈 *

\************************************/

#include #include #include #include #include #include const int maxn = 10010, size = 0xffff;

struct edge

edge(int v, edge *next): v(v), next(next) {}

} *edge[maxn], tmp[maxn], *tot = tmp; bool marked[maxn], use[maxn][maxn];

int dist[maxn], pre[maxn], deg[maxn], deg[maxn], res[maxn], root, n, m, ans;

inline int bfs(int s)

void dfs(int u)

if (pos) dfs(pos); use[u][pos] = use[pos][u] = 1;

for (edge *p = edge[u]; p; p = p -> next) if (!marked[p -> v])

dfs(p -> v), use[u][p -> v] = use[p -> v][u] = 1;

return;

}int main()

for (int t = 0; t < 1000; ++t)

}printf("%d\n", ans);

for (int i = 0; i < ans; ++i) printf("%d\n", res[i]);

return 0;

}

隨機化搜尋

參與考古挖掘的小明得到了乙份藏寶圖,藏寶圖上標出了 nn 個深埋在地下的寶藏屋,也給出了這 nn 個寶藏屋之間可供開發的mm 條道路和它們的長度。小明決心親自前往挖掘所有寶藏屋中的寶藏。但是,每個寶藏屋距離地面都很遠,也就是說,從地面打通一條到某個寶藏屋的道路是很困難的,而開發寶藏屋之間的道路 則相...

HAOI2006 均分資料 dp,隨機化

將 n 個數分成 m 組,使得各組資料的數值和最平均,即各組的均方差最小。n leq 20,m leq 6 考慮如果是按順序分段,那麼設 f i 表示前 i 個數積攢的最小方差,dp即可 用std random shuffle隨機若干順序,可以證明在很大概率上能隨到答案 當然內部也可以貪心,每次盡量...

6 28 NOI模擬賽 好題 狀壓dp 隨機化

算是一道比較新穎的題目 儘管好像是兩年前的省選模擬賽題目。對於20 的分數 可以進行爆搜,對於另外20 的資料 因為k很小所以考慮上狀壓dp.觀察最後答案是乙個連通塊 從而可以發現這個連通塊必然存在乙個深度最淺的點且唯一 所以隨便找乙個點做根然後對自己子樹內尋找答案就可以是正確的。考慮另外的30 的...