zoukankan      html  css  js  c++  java
  • BZOJ-2535 航空管制 toposort

    题目传送门

    题解:

    如果正着连边,可以发现最困难的点是ti不好处理。

    所以我们连反边,然后将ti转换成前面有n-ti+1架飞机起飞了作为限制条件。

    对于第一问,直接toposort 然后反着输出求出的结果。

    对于第二问,我们则枚举每个架飞机,然后在toposort的时候不把这个点入队,直到队列为空的时候,这个时候就是这架飞机的最早起飞时间了。

    代码:

    /*
    code by: zstu wxk
    time: 2019/02/22
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 1e5 + 100;
    int n, m;
    vector<int> vc[N];
    vector<int> e[N];
    int ind[N], vis[N], t[N], ans[N];
    void init(){
        for(int i = 1; i <= n; ++i) ind[i] = vis[i] = 0;
        for(int i = 1; i <= n; ++i){
            for(int j = 0; j < e[i].size(); ++j){
                int v = e[i][j];
                ++ind[v];
            }
        }
    }
    int toposort(int ban){
        queue<int> q;
        for(int j = 0; j < vc[n].size(); ++j){
            int v = vc[n][j];
            if(!ind[v] && v != ban){
                q.push(v);
                vis[v] = 1;
            }
        }
        for(int k = n; k >= 1; --k){
            if(q.empty()) return k;
            int x = q.front();
            q.pop();
            ans[k] = x;
            for(int j = 0; j < e[x].size(); ++j){
                int v = e[x][j];
                if(v == ban) continue;
                ind[v]--;
                if(ind[v] == 0 && t[v] >= k && !vis[v]){
                    vis[v] = 1;
                    q.push(v);
                }
            }
            for(int j = 0; j < vc[k-1].size(); ++j){
                int v = vc[k-1][j];
                if(v == ban) continue;
                if(!vis[v] && ind[v] == 0){
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
        return 1;
    }
    void Ac(){
        for(int i = 1; i <= n; ++i){
            scanf("%d", &t[i]);
            vc[t[i]].pb(i);
        }
        for(int i = 1,u,v; i <= m; ++i){
            scanf("%d%d", &u, &v);
            e[v].pb(u);
        }
        init();
        toposort(0);
        for(int i = 1; i <= n; ++i){
            printf("%d%c", ans[i], " 
    "[i==n]);
        }
        for(int i = 1; i <= n; ++i){
            init();
            printf("%d%c", toposort(i), " 
    "[i==n]);
        }
    }
    int main(){
        while(~scanf("%d%d", &n, &m)){
            Ac();
        }
        return 0;
    }
    /*
    5 5
    4 5 2 5 4
    1 2
    3 2
    5 1
    3 4
    3 1
    
    */
    View Code
  • 相关阅读:
    ABP AsyncHelper.RunSync 内部实现
    ABP 扩展 OrganizationUnit 数据实体(新增字段)
    ABP 调用 PUT 接口报错 405 Method Not Allowed
    ABP 扩展 Role 数据实体(新增字段)
    C# EntityFramework 自定义数据库表名(一)
    EPPlus.Core(OfficeOpenXml) 获取 Excel 数据集合
    C# 获取文件并将文件按创建/修改时间排序
    C# 计算两个日期之间的月份数(差值)
    C# Split 方法扩展支持双引号
    教你在 C# 代码中写出带高亮关键字的注释
  • 原文地址:https://www.cnblogs.com/MingSD/p/10419339.html
Copyright © 2011-2022 走看看