POJ3687拓扑排序+贪心
生活随笔
收集整理的這篇文章主要介紹了
POJ3687拓扑排序+贪心
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給你n個求,他們的重量是1-n(并不是說1號求的重量是1...),然后給你m組關系a,b,表示a的重量小于b的重量,然后讓你輸出滿足要求的前提下每個球的重量,要求字典序最小。
思路:
? ? ? 給你n個求,他們的重量是1-n(并不是說1號求的重量是1...),然后給你m組關系a,b,表示a的重量小于b的重量,然后讓你輸出滿足要求的前提下每個球的重量,要求字典序最小。
思路:
? ? ? 很容易想到這個可以用拓撲排序(其實如果沒有字典序那個要求的話查分約束也行),還有就是這個里面的字典序最小不是說拓撲排序的字典序最小,這個要整清楚,如果是求拓撲排序的序列字典序最小直接在出隊列的時候找一個編號最小的就行,但是這個不是,我們必須要逆向建邊,然后逆向分配編號,因為正向的話會出問題,比如剛開始有好幾個入度是0,但是我們無法找到該現則那個會最早碰到1號位置,這個自己畫一下就清楚了,一開始我想的是差分約束+并查集之后二級排序,排序的依據是如果當前這兩個點是同一個父親,那么按照距離排序,否則按照id排序,其實這樣邏輯沒錯,但是sort本身不可以這樣用的,因為這兩個限制條件并不是那種一個建立在另一個的基礎上的那種,這個說不太清楚,自己好好和xy的那個二級排序對比下就明白了,還有這個題目數據并不是很大,做法不唯一,直接搜索理論上沒啥大問題,如果是上面說的那種逆向的拓撲排序的話其實有點貪心的意思。
#include<queue> #include<stdio.h> #include<string.h>#define N_node 200 + 10 #define N_edge 40000 + 400using namespace std;typedef struct {int to ,next; }STAR;typedef struct NODE {int x;friend bool operator < (NODE a, NODE b){return a.x < b.x;} }NODE;STAR E[N_edge]; int s_x[N_node] ,in[N_node]; int list[N_node] ,tot; NODE xin ,tou;void add(int a ,int b) {E[++tot].to = b;E[tot].next = list[a];list[a] = tot; }bool Sort_TP(int n) {priority_queue<NODE>q;for(int i = 1 ;i <= n ;i ++)if(!in[i]){xin.x = i;q.push(xin);}int nowsort = n;while(!q.empty()){tou = q.top();q.pop();s_x[tou.x] = nowsort --;for(int k = list[tou.x] ;k ;k = E[k].next){xin.x = E[k].to;if(!--in[xin.x]) q.push(xin);}}return nowsort == 0; }int main () {int t ,n ,m ,i ,a ,b;scanf("%d" ,&t);while(t--){scanf("%d %d" ,&n ,&m);memset(list ,0 ,sizeof(list)) ,tot = 1;memset(in ,0 ,sizeof(in));for(i = 1 ;i <= m ;i ++){scanf("%d %d" ,&a ,&b);add(b ,a);in[a] ++;}if(Sort_TP(n)){for(i = 1 ;i <= n ;i ++)if(i == n) printf("%d\n" ,s_x[i]);else printf("%d " ,s_x[i]);}else{printf("-1\n");continue;}}return 0; }
總結
以上是生活随笔為你收集整理的POJ3687拓扑排序+贪心的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ3614奶牛晒阳光DINIC或者贪
- 下一篇: ZOJ3261并查集逆向处理