題目大意:
給出乙個序列(0~n-1),這個序列經過某個變換會成為另外乙個序列,但是其中的元素不會改變,給出初始序列與變換後的序列每一位上的「距離」,求字典序最小的變換序列。#cp
題解:匈牙利求二分圖的最大匹配
//居然a了qwq好感人
就是把乙個元素跟它能變幻到的連邊,(為什麼我感覺可以有四種orz然後大家說的是最多兩條邊可能是我沒有仔細研究=-=)。然後跑匈牙利看看能否完美匹配就好了。
由於方案要字典序最小,所以考慮選邊的順序。讓比較小的先被選到,就是大的先連。而匈牙利中從n-1開始匹配。因為越早匹配完成,後面的點如果與前面的產生衝突,那麼一定是先完成匹配的點(編號更大的)的匹配點變大。
#include#include#include#include#includeusing namespace std;
#define maxn 10100
struct node
a[maxn*4];int len,first[maxn];
int d[maxn],as[maxn],bf[maxn],ask[maxn],tim;
void ins(int x,int y)
bool ffind(int x)
} return false;
}int main()
else
}ans=tim=0;
memset(bf,-1,sizeof(bf));
memset(ask,0,sizeof(ask));
for (i=n-1;i>=0;i--)
if (ans!=n) printf("no answer\n");
else
{ printf("%d",as[0]);
for (i=1;i
BZOJ1562 NOI2009 變換序列
1 題意 題意有些難理解 2 分析 我們發現如果要求判斷是否合法的話就so easy了,二分圖匹配即可,但是我們發現要求輸出字典序最小的,那麼我們在匈牙利的時候就倒著列舉,另外鄰接表中的邊一定要排好序,如果用的是鍊錶的話,就從大到小,vector就從小到大插入,然後我們就可以保證字典序最小了,想了半...
bzoj1562 Noi2009 變換序列
題意 給乙個序列di表示min i ti n i ti 求乙個字典序最小的序列ti sol 對於每個i,能和它連邊的只有i di和 i di n n 將圖轉為二分圖,左邊為i,右邊為ti,跑匈牙利演算法 為避免陣列下標越界 memset 1之類麻煩的問題,右移一位處理 p.s.行末不能有空格,文末有...
NOI2009 bzoj1562 變換序列
可以把距離看成每個點都有兩個匹配點,這樣就是求字典序最小的二分圖匹配。先任意求出乙個,然後從小到大考慮每個點,嘗試更換他的匹配點,但是要求不能改動之前的匹配。include include using namespace std const int maxn 10010 int a maxn fir...