1. 程式人生 > >Gym - 102059D 2018-2019 XIX Open Cup, Grand Prix of Korea D. Dumae 貪心+堆

Gym - 102059D 2018-2019 XIX Open Cup, Grand Prix of Korea D. Dumae 貪心+堆

-- 當前位置 amp turn top tro ems 超過 ret

題面

題意:有3e5個人排成一列,然後Li,Ri表示每個人可以站在[Li,Ri]中的一個,然後M(1e6)個限制條件,某個人一定要在某個人前面,求一種合法方案,無解輸出-1

題解:首先可以想到對於限制條件,先進行拓撲排序,如果不能則無解

針對拓撲排序的結果,可以更精確每個人站的位置的區間[Li,Ri]

然後從後往前進行考慮,我們考慮每個位置由誰來坐比較好,那我們策略是,R能覆蓋這個位置的中,L最大的那一個來最優,

我們一直維護一個R的堆,每次我們將R超過當前位置的人都丟進一個新的堆裏,這個堆按L大來排序,再使用最大的那個L

如此貪心做完,不行則無解

  1 #include<bits/stdc++.h>
  2 #define lld long long 
  3 #define N 300005
  4 using namespace std;
  5 vector<int> g[N];
  6 int n,m,du[N],x,y,ans[N];
  7 struct rec
  8 {
  9     int l,r,id;
 10     bool operator <(const rec& a)const 
 11     {
 12         if (r!=a.r) return
r<a.r; 13 return l>a.l; 14 } 15 }a[N]; 16 struct ssy 17 { 18 int l,r,id; 19 bool operator <(const ssy& a)const 20 { 21 return l<a.l; 22 } 23 }b[N]; 24 int ask() 25 { 26 priority_queue<ssy>q; 27 priority_queue<rec>qq;
28 ssy st; 29 while (!q.empty()) q.pop(); 30 while (!qq.empty()) qq.pop(); 31 for (int i=1;i<=n;i++) if (du[i]==0) qq.push(a[i]); 32 for (int i=n;i>=1;i--) 33 { 34 while (!qq.empty()) 35 { 36 if (qq.top().r<i) break; 37 q.push(b[qq.top().id]); 38 // cout << b[qq.top().id].id << endl; 39 qq.pop(); 40 } 41 if (q.empty() || q.top().l>i) return 0; 42 st=q.top(); 43 // cout<<st.id << endl; 44 q.pop(); 45 46 //cout<<"id"<<st.id<<endl; 47 ans[i]=st.id; 48 49 for (int j=0;j<g[st.id].size();j++) 50 { 51 int u=g[st.id][j]; 52 du[u]--; 53 if (du[u]==0) qq.push(a[u]); 54 } 55 } 56 return 1; 57 } 58 int c[N]; 59 bool dfs(int u) 60 { 61 c[u]=-1; 62 for (int v=0;v<g[u].size();v++) 63 { 64 int to=g[u][v]; 65 if (c[to]<0) 66 { 67 //cout<<"u xxx:"<<u<<endl; 68 //cout<<"1 xxx:"<<to<<endl; 69 return 0; 70 }else 71 if (!c[to] && !dfs(to)) 72 { 73 //cout<<"u xxx:"<<u<<endl; 74 //cout<<"1 xxx:"<<to<<endl; 75 return 0; 76 } 77 a[u].l=max(a[u].l,a[to].l+1); 78 b[u].l=a[u].l; 79 } 80 c[u]=1; 81 return 1; 82 } 83 bool toposort() 84 { 85 memset(c,0,sizeof(c)); 86 for (int u=1;u<=n;u++) if (!c[u]) 87 if (!dfs(u)) return 0; 88 return 1; 89 } 90 int main() 91 { 92 scanf("%d%d",&n,&m); 93 for (int i=1;i<=n;i++) 94 { 95 scanf("%d%d",&a[i].l,&a[i].r);a[i].id=i; 96 b[i].l=a[i].l; 97 b[i].r=a[i].r; 98 b[i].id=a[i].id; 99 } 100 for (int i=1;i<=m;i++) 101 { 102 scanf("%d%d",&x,&y); 103 g[y].push_back(x); 104 du[x]++; 105 } 106 if (!toposort()) printf("-1\n");else 107 if (!ask()) printf("-1\n");else 108 for (int i=1;i<=n;i++) printf("%d\n",ans[i]); 109 110 111 //for (int i=1;i<=n;i++) cout<<a[i].l<<" "<<a[i].r<<endl; 112 }

Gym - 102059D 2018-2019 XIX Open Cup, Grand Prix of Korea D. Dumae 貪心+堆