您的位置:首页 > 其它

BZOJ2535: [Noi2010]Plane 航空管制2

2015-11-25 14:33 393 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2535

把图反向,拓扑排序一下,用并查集维护当前权值能放置的最大位置。对于第二问,就相当于我把点i ban掉然后去找最后一个!ans[i]的位置。那么第一问就哪个点都不ban而已。

#include<cstring>
#include<cctype>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define ll long long
#define maxn 2005
#define mm int(1e9+7)
using namespace std;
struct edge{int obj,pre;
}e[200500];
int ans[maxn],mn[maxn],d[maxn],t[maxn],head[maxn],dd[maxn],fa[maxn],q[maxn];
int n,m,x,y,tot,cnt,ban;
void insert(int x,int y){
e[++tot].obj=y; e[tot].pre=head[x]; head[x]=tot;
}
int read(){
int x=0,f=1; char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int get(int x){
if (fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void dp(int ban){
rep(i,1,n) d[i]=dd[i],fa[i]=i,ans[i]=0,mn[i]=min(n,t[i]); cnt=0;
rep(i,1,n) if (!d[i]) q[++cnt]=i;
while (cnt){
int u=q[cnt--];
if (u==ban) continue;
int pos=get(mn[u]); ans[pos]=u; fa[pos]=pos-1;
for (int j=head[u];j;j=e[j].pre){
int v=e[j].obj; d[v]--;
mn[v]=min(mn[v],mn[u]);
if (!d[v]) q[++cnt]=v;
}
}
}
int main(){
n=read(); m=read();
rep(i,1,n) t[i]=read();
rep(i,1,m){
x=read(); y=read();
insert(y,x);
dd[x]++;
}
dp(0);
rep(i,1,n-1) printf("%d ",ans[i]); printf("%d\n",ans
);
rep(i,1,n){
dp(i);
down(j,n,1) if (!ans[j]) {
printf("%d%c",j,i==n?'\n':' ');
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: