BZOJ 2535 Plane 航空管制2

http://www.lydsy.com/JudgeOnline/problem.php?id=2535

思路:对于1,我们只需要每个点比前驱大就可以了,然后满足尽量优。

对于第二问,我们先求出这个点前驱有几个,记为ans,cnt=ans

每访问一个未访问的点,cnt++

然后对于后面的点从少往大排,若有k>ans,那么一定在我们当前处理这个点前面,ans++

若有k<=cnt,说明要i放在这个点的后面,因此ans=k+1

记得不要省方便add(read(),read()),好像会出错。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 struct node{
 7     int k,id;
 8 }p[200005];
 9 int tot=0,go[200005],next[200005],first[200005];
10 int A[200005],n,m,vis[200005],cnt;
11 int read(){
12     int t=0,f=1;char ch=getchar();
13     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
14     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
15     return t*f;
16 }
17 void insert(int x,int y){
18     tot++;
19     go[tot]=y;
20     next[tot]=first[x];
21     first[x]=tot;
22 }
23 void add(int x,int y){
24     insert(x,y);insert(y,x);
25 }
26 void init(){
27     n=read();m=read();
28     for (int i=1;i<=n;i++) p[i].k=read(),p[i].id=i;
29     for (int i=1;i<=m;i++){
30         int x=read(),y=read();
31         add(x,y);
32     }
33 }
34 bool cmp(node q,node w){
35     return q.k<w.k;
36 }
37 bool deal(int x){
38     for (int i=first[x];i;i=next[i]){
39         if (i&1){
40             int pur=go[i];
41             p[x].k=std::min(p[x].k,p[pur].k-1);
42         }
43     }
44 }
45 void solve1(){
46     for (int j=1;j<=n;j++)
47      for (int i=1;i<=n;i++)
48       deal(i);
49     std::sort(p+1,p+1+n,cmp);  
50     for (int i=1;i<n;i++) printf("%d ",p[i].id);
51     printf("%d
",p[n].id);
52 }
53 int count(int x){
54     int res=0;vis[x]=1;
55     for (int i=first[x];i;i=next[i]){
56         int pur=go[i];
57         if (!vis[pur]&&(i%2==0)){
58             res+=count(pur);
59         }
60     }
61     return res+1;
62 }
63 void solve2(){
64     for (int i=1;i<=n;i++){
65         memset(vis,0,sizeof vis);
66         int ans=count(i);
67         cnt=ans;
68         for (int j=1;j<=n;j++) 
69          if (!vis[p[j].id]){
70                 cnt++;
71                 if (p[j].k<=ans) ans++;
72                 else if (cnt>p[j].k) ans=p[j].k+1;
73          }
74         A[i]=ans; 
75     }
76     for (int i=1;i<n;i++) printf("%d ",A[i]);
77     printf("%d
",A[n]);
78 }
79 void work(){
80     solve1();
81     solve2();
82 }
83 int main(){
84     init();
85     work();
86 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5601853.html