洛谷 [NOI2010] 航空管制

难度较高的一道题(当时第一遍做没啥思路),转换比较难想

拓扑+最短路

CODE

#include<bits/stdc++.h>
using namespace std;
#define N 10005
int n,m,k[2505];
int tot,head[N],ver[N],Next[N];
int in[2505],t[2505];
int ans[2505];
void add(int x,int y){
    ver[++tot]=y;
    Next[tot]=head[x],head[x]=tot;
}
void topu(){
    priority_queue<pair<int,int> > q;
    for(int i=1;i<=n;++i)
        if(!in[i]) q.push(make_pair(k[i],i));
    int cnt=0;
    while(q.size()){
        int x=q.top().second;q.pop();
        ans[++cnt]=x;
        for(int i=head[x];i;i=Next[i]){
            int y=ver[i];
            if(--in[y]==0) q.push(make_pair(k[y],y));
        }
    }
    for(int i=n;i>=1;--i) printf("%d%c",ans[i],i==1?'\n':' ');
}
int work(int s){
   priority_queue<pair<int,int> > q;
   for(int i=1;i<=n;++i) {
        in[i]=t[i];
        if(!in[i]) q.push(make_pair(k[i],i));  
    }
    int cnt=n;
    int flag=0;
    while(q.size()){
        int x=q.top().second;q.pop();
        if(x==s) continue;
        if(cnt>k[x]) break;
        --cnt;
        for(int i=head[x];i;i=Next[i]){
            int y=ver[i];
            if(--in[y]==0) q.push(make_pair(k[y],y));
        }
    }
    return cnt;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i) 
        scanf("%d",&k[i]);
    for(int i=1;i<=m;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        add(v,u);
        in[u]++;
    }
    for(int i=1;i<=n;++i)
        t[i]=in[i];
    topu();
    for(int i=1;i<=n;++i)
         printf("%d%c",work(i),i==n?'\n':' ');
    return 0;
}

 

posted @ 2022-02-13 10:59  LikC1606  阅读(60)  评论(0)    收藏  举报