库存

这些题目考试时费劲心思没有想出,考完后发现是一个有意思的贪心dp,挺奇妙的,没有接触过,所以记在这里,方便回顾。

 

数分考试

ZR提高十连测day9 T1 problem440 

一共有$n$个人参加了考试。第$i$个人的名次区间是$[L_i,R_i]$。除此之外,又有$m$条其他信息,形如$u_i,v_i$,表示第$u_i$个人考的要比$v_i$好(即排名更低)。是否有一个合法的排名,满足上述所有的要求。如果有,请输出任意一组解,否则输出"-1"(不含括号)。$n \leq 3\times 10^5, m\le 10^6$

分析

首先建反图拓扑,然后拓扑的过程中,判断是否存在环。用优先队列,每次弹出左端点最靠右的人,左端点相同弹右端点最靠右的,这样首先保证了图上的关系,然后又是尽量靠右的。记录一个Ti,从后往前依次更新第Ti名的人是谁。

一些考试题,没想出来的各种贪心dp一类的
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<cctype>
 7 #include<set>
 8 #include<vector>
 9 #include<queue>
10 #include<map>
11 #define fi(s) freopen(s,"r",stdin);
12 #define fo(s) freopen(s,"w",stdout);
13 using namespace std;
14 typedef long long LL;
15 
16 char buf[100000], *p1 = buf, *p2 = buf;
17 #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
18 inline int read() {
19     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
20     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
21 }
22 
23 const int N = 300005;
24 
25 struct Edge{
26     int to, nxt;
27     Edge() { }
28     Edge(int a,int b) { to = a, nxt = b; }
29 }e[2000005];
30 struct Node{
31     int l, r, id;
32     bool operator < (const Node &A) const {
33         return l == A.l ? r < A.r : l < A.l;
34     }
35 }A[N];
36 int head[N], deg[N], ans[N], n, En;
37 bool vis[N];
38 priority_queue< Node >q;
39 
40 void add_edge(int u,int v) {
41     ++En; e[En] = Edge(v, head[u]); head[u] = En;
42 }
43 bool topo() {
44     int L = 1, R = 0;
45     for (int i = 1; i <= n; ++i) 
46         if (!deg[i]) q.push(A[i]);
47     int Ti = n;
48     while (!q.empty()) {
49         Node now = q.top(); q.pop();
50         if (now.l > Ti || now.r < Ti) return 0;
51         vis[now.id] = 1;
52         ans[Ti --] = now.id;
53         for (int i = head[now.id]; i; i=e[i].nxt) 
54             if ((--deg[e[i].to]) == 0) q.push(A[e[i].to]);
55     }
56     for (int i = 1; i <= n; ++i) 
57         if (!vis[i]) return 0;
58     return 1;
59 }
60 int main() {
61     n = read(); int m = read();
62     for (int i = 1; i <= n; ++i) 
63         A[i].l = read(), A[i].r = read(), A[i].id = i;
64     for (int i = 1; i <= m; ++i) {
65         int u = read(), v = read();
66         add_edge(v, u); deg[u] ++;
67     }
68     if (!topo()) { cout << -1; return 0; }
69     for (int i = 1; i <= n; ++i) printf("%d\n",ans[i]);
70     return 0;
71 }
72 /*
73 4 3
74 
75 3 4
76 1 3
77 2 4
78 2 3
79 
80 2 3
81 3 4
82 2 1
83 */
View Code

相关文章:

  • 2021-12-28
  • 2022-12-23
  • 2021-06-20
  • 2022-12-23
  • 2021-10-01
  • 2021-09-08
  • 2022-02-25
  • 2021-09-19
猜你喜欢
  • 2022-12-23
  • 2021-09-20
  • 2022-12-23
  • 2021-05-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案