您的位置:首页 > 其它

BZOJ 2535 Plane 航空管制2

2016-06-20 21:10 246 查看
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()),好像会出错。

#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
struct node{
int k,id;
}p[200005];
int tot=0,go[200005],next[200005],first[200005];
int A[200005],n,m,vis[200005],cnt;
int read(){
int t=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
return t*f;
}
void insert(int x,int y){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
}
void add(int x,int y){
insert(x,y);insert(y,x);
}
void init(){
n=read();m=read();
for (int i=1;i<=n;i++) p[i].k=read(),p[i].id=i;
for (int i=1;i<=m;i++){
int x=read(),y=read();
add(x,y);
}
}
bool cmp(node q,node w){
return q.k<w.k;
}
bool deal(int x){
for (int i=first[x];i;i=next[i]){
if (i&1){
int pur=go[i];
p[x].k=std::min(p[x].k,p[pur].k-1);
}
}
}
void solve1(){
for (int j=1;j<=n;j++)
for (int i=1;i<=n;i++)
deal(i);
std::sort(p+1,p+1+n,cmp);
for (int i=1;i<n;i++) printf("%d ",p[i].id);
printf("%d\n",p
.id);
}
int count(int x){
int res=0;vis[x]=1;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (!vis[pur]&&(i%2==0)){
res+=count(pur);
}
}
return res+1;
}
void solve2(){
for (int i=1;i<=n;i++){
memset(vis,0,sizeof vis);
int ans=count(i);
cnt=ans;
for (int j=1;j<=n;j++)
if (!vis[p[j].id]){
cnt++;
if (p[j].k<=ans) ans++;
else if (cnt>p[j].k) ans=p[j].k+1;
}
A[i]=ans;
}
for (int i=1;i<n;i++) printf("%d ",A[i]);
printf("%d\n",A
);
}
void work(){
solve1();
solve2();
}
int main(){
init();
work();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: