题意:有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 }