以小球為模型,實際上就是找滿足條件的最小字典序
比如:我們有這樣一組資料
1
4 24 1
3 2
意思就是1組測試樣例,4代表乙個序列,[1,2,3,4],我們要做的就是調整下次序,使它滿足兩個條件。
處於4號位的數字要比處於1號位的數字要小,處於3號位的數字要比處在2號位的數字小。
我們隨便一想,就有兩組序列[4,3,2,1] [2,4,3,1].然後題目說讓我們輸出字典序最小的,那我們輸出[2,4,3,1]就好了。
拓撲排序,在滿足約束條件的前提下,要先保證1號球最輕,如果我們由輕的向重的連邊,然後我們依次有小到大每次把重量分給乙個入度為0的點,那麼在拓撲時我們面對多個入度為0的點,我們不知道該把最輕的分給誰才能以最快的速度找到1號(使1號入度為0),並把當前最輕的分給1號。所以我們要由重的向輕的連邊,然後從大到小每次把乙個重量分給乙個入度為0的點。這樣我們就不用急於探求最小號。我們只需要一直給最大號附最大值,盡量不給小號賦值,這樣自然而然就會把輕的重量留給小號。
我們可以轉化為球入洞問題,這樣比較好描述,數字[1-n]是球,數字[1-n]是洞。
正向拓撲排序思路,從1開始遍歷球,拓撲排序,最快找到1數字(洞),這樣就能把數字最小的球放入第乙個洞中。但是我們如何最快的找到叫1的洞呢。無法辦到。(拓撲排序只能滿足當前狀態,沒有記憶性)
逆向拓撲排序思路,從n開始遍歷球,拓撲排序,"""不用最快找到數字n的洞""",只需要找到可以接收n球的洞就好。那麼我們排序到最後,就能保證,1數字的洞,(在滿足約束條件的情況下)是球最小的。
#include#include#includeusing namespace std;
const int maxv=210;
int in[maxv],mmap[maxv][maxv],num[maxv];
int main(void)
bool flag=false;
for( i=n; i>=1; i--)
}if(j==0)
}if(flag==false)
for(int i=1; i<=n; i++)
cout
cout<<-1<}
return 0;
}
POJ 3687 逆向拓撲排序
題意 n個球,m個關係,a b 代表 a 比 b 輕,按編號1 n輸出每個球是第幾大,要使得編號小的球排名盡量小.例如 5 6 1 4 3 2 1號球可以是第3,4,5,6重 這裡要選第三重,那麼二號球就只能是最重的乙個了,即6.輸出答案為 3 6 5 4 1 2 思路 反向建立拓撲排序,則以重的球...
poj 3687 拓撲排序
hiahiahia我又回來了!傳送 題意 理解題意很重要嗯 給定幾個標籤球的重量大小關係,求每個球是第幾重的 即每個球在所有球的重量中由小到大排名是多少 也可以認為是重量嘛,就是第1號位置的球重4一類的。如果存在多種可行解,就按編號小得重量盡量小輸出 重點 思路 拓撲。但是 逆序的!why?因為正序...
poj 3687 反向拓撲尋求字典序最小解
看題意可得,這道題很明顯是反向拓撲排序求解的問題,只不過反向拓撲排序求的是標籤的順序,之後還有把每個標籤所對應的質量聯絡起來就好。include include include include include includeusing namespace std const int maxn 210...