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

题面

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

 

posted @ 2019-03-25 10:24  口香糖万岁  阅读(504)  评论(0编辑  收藏  举报