zoukankan      html  css  js  c++  java
  • bzoj 2535: [Noi2010]Plane 航空管制2【拓扑排序+堆】

    有个容易混的概念就是第一问的答案不是k[i]字典序最小即可,是要求k[i]大的尽量靠后,因为这里前面选的时候是对后面有影响的(比如两条链a->b c->d,ka=4,kb=2,kc=3,kd=4,按字典序就先选c然后b就不能合法了)
    所以倒着来,建反图,然后按照n-k[i]从大到小拓扑,因为是反图所以是k大的尽量靠后
    然后考虑第二问,是当前点x在拓扑中能入队先不入,直到某个点非法再入,这样虽然顺序变了但是非法点的排名不变所以依然合法

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int N=2005;
    int n,m,a[N],h[N],cnt,c[N],d[N],ans[N],tot;
    struct qwe
    {
    	int ne,to;
    }e[N*10];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void add(int u,int v)
    {
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	h[u]=cnt;
    }
    inline int wk(int x)
    {
        tot=0;
        priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
        for(int i=1;i<=n;i++) 
    		d[i]=c[i];
        for(int i=1;i<=n;i++)
    		if(!d[i]) 
    			q.push(make_pair(n-a[i],i));
        while(!q.empty())
        {
            int u=q.top().second;
            q.pop();
            if(u==x) 
    			continue;
            if(n-tot>a[u]) 
    			return n-tot;
            tot++;
            for(int i=h[u];i;i=e[i].ne)
                if(!(--d[e[i].to]))
    				q.push(make_pair(n-a[e[i].to],e[i].to));
        }
        return n-tot;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        for(int i=1;i<=m;i++)
    	{
    		int x=read(),y=read();
    		add(y,x);
    		d[x]++;
    	}
        for(int i=1;i<=n;i++) 
    		c[i]=d[i];
    	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
        for(int i=1;i<=n;i++)
            if(!d[i]) 
    			q.push(make_pair(n-a[i],i));
        while(!q.empty())
        {
            int u=q.top().second;
            q.pop();
            ans[++tot]=u;
            for(int i=h[u];i;i=e[i].ne)
                if(!(--d[e[i].to]))
    				q.push(make_pair(n-a[e[i].to],e[i].to));
        }
        for(int i=n;i>=1;i--)
            printf("%d ",ans[i]);
        puts("");
        for(int i=1;i<=n;i++)
            printf("%d ",wk(i));
        return 0;
    }
    
  • 相关阅读:
    long和Long的区别
    C语言的变量的内存分配
    Java蓝桥杯 算法提高 九宫格
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
  • 原文地址:https://www.cnblogs.com/lokiii/p/10833944.html
Copyright © 2011-2022 走看看