2023年noi全國競賽
時間限制: 1 s
空間限制: 128000 kb
題目等級 : 大師 master
題解
description
對於n個整數0,1,…,n-1,乙個變換序列t可以將i變成ti,其中:ti∈且ui=1 to n-1 =。任意x,y∈,定義x和y之間的距離d(x,y)=min。給定每個i和ti之間的距離d(i,ti),你需要求出乙個滿足要求的變換序列t。如果有多個滿足條件的序列,輸出其中字典序最小的乙個。
說明:對於兩個變換序列s和t,如果存在p輸入描述
input description
輸入檔案中的第一行為乙個整數n,表示序列的長度。
接下來的一行為n個整數di,其中:di表示i和ti之間的距離。
輸出描述
output description
如果至少存在乙個滿足要求的變換序列t,則輸出一行為n個整數,表示你計算得到的字典序最小的t;否則輸出「no answer」(不含引號)。
輸出檔案中相鄰兩個數字之間用乙個空格分開,行末不包含多餘空格。
樣例輸入
sample input
1 1 2 2 1
樣例輸出
sample output
1 2 4 0 3
資料範圍及提示
data size & hint
對於30%的資料,滿足:n<=50;
對於60%的資料,滿足:n<=500;
對於100%的資料,滿足:n<=10000。
分類標籤 tags 點此展開
大陸地區
noi全國競賽
2023年
我現在簡要述說一下這一題的意思:題目的意思就是給出x對y的對應關係:,現在給出d(x,y)和x,求y,並且要求字典序最小的y。(x這組數是從0到n-1,y這組數屬於0到n-1)
下面分析一下樣例就更加方便理解這個題目了:
xd(x,y)
y1
2
4
0
3
表一樣例輸入中給了n為5,,所以表一第一行x的值也是從0到4。表一的第二行d(x,y)就是輸入資料的x,y的關係。最後需要我們求的就是表一第三行的y的資料。
我們可以看到上表中的(每列)每組x,y,d(x,y)都是滿足關係,比如x=0,d(x,y)=1,y=1這一列,
|x-y|=1,n-|x-y|=4,故d(x,y)=1,所以關係成立,後面的以此類推。
我們在仔細來看一下關係式,發現對於這樣的乙個關係式,我們知道d(x,y)和x,求y的話,y最多有四個值,不過其實仔細拿例項出來分析之後,就發現這四個值是可以變成兩個值的。
看到題目,發現題目是乙個赤裸裸的二分匹配。這個題目可以用匈牙利演算法來做,匈牙利演算法的時間複雜度是o(nm),在這裡是完全ok的。
這個題目還有另外乙個難點,就是要求字典序最小的y,其實求最小的y可以在尋找交錯路(匹配關係)的時候倒序尋找,不過這樣做的時候要注意,在存邊關係的連線表的時候要注意從小往大存,確保從字典序小的邊找起。
因為如果正序查詢,按照匈牙利演算法的演算法規則,那麼一定是找到的字典序最大的那個。
問題:求二分圖最大匹配可以用最大流(maximal flow)或者匈牙利演算法(hungarian algorithm)
總結:其實這個題目就是二分匹配中的匈牙利演算法,套用下匈牙利的模板,再想好怎麼輸出字典序最小的y就ok了。
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10#define maxn 10010
11using
namespace
std;
1213
1415
int graph[maxn][2];//
每個點最多連出2條邊,存邊時保證graph[i][0]
1617
int vis[maxn];//
表示節點是否被訪問
18int match[maxn];//
y集合中的點i與x集合的match[i]匹配
19int ans[maxn];//
用於輸出結果
20int
n;21
22//
用來構建關係,確保字典序小的存在前面
23void addedge(int i,int
ver)
2430
else
if(graph[i][0]>ver)
3135
else graph[i][1]=ver;36}
37//
匈牙利演算法中的尋找交錯路
38bool crosspath(int
ns)3951}
52return
false;53
}54//匈牙利演算法倒敘從每個點找交錯路,確保求出最小字典序y
55int
find()
5665
return
tot;66}
6768
6970
intmain()
7185
if(find()//
未能完全匹配則無解。
8690
//統計答案輸出。
91for(int i=0;ii;
92 printf("
%d",ans[0
]);93
for(int i=1;i"%d"
,ans[i]);
94return0;
95 }
NOI2009 變換序列
讀懂題意後發現這道題最主要是要求出字典序最小的排列,考察了匈牙利演算法的實質。首先對於 d i 的定義,我們可以解出可能的 t i 然後將 i 與 t i 連邊,求最大匹配。如果最大匹配 但是要求字典序最小。第一中方法在我 ac 後翻看題解而寫的。這個程式是根據匈牙利演算法的實質寫的。對於乙個待匹配...
NOI2009 變換序列
51 1 2 2 1 1 2 4 0 3 30 的資料中n 50 60 的資料中n 500 100 的資料中n 10000。二分圖匹配 匈牙利演算法的原理是衝突時替換 不過要求字典序最小,乙個點會連出2條邊,加邊先加入大的,這樣在匹配時就會先匹配小的 不過這是針對於鏈式前向星 然後如果i和j都匹配了...
NOI2009 變換序列
here 簡要題意就是給定乙個排列,每個元素有兩個對應關係,問你是否能將該排列轉換為另乙個排列,並使之字典序最小,如果不考慮字典序的話,這題就是裸的一道求二分圖完美匹配的題,那麼我們該如何考慮字典序呢?我們可以按字典序暴力列舉左邊的點與右邊的哪個點相匹配,再跑二分圖。實際上我們可以不這樣做,二分圖匹...