zoukankan      html  css  js  c++  java
  • 「Luogu P5603」小O与桌游

    题目链接

    戳我

    (Solution)

    我们来分析题目。

    实际上就是求一个拓扑序满足拓扑序的前缀最大值最多/最少

    对于第一种情况,很明显一直选当前能选的最小的是最优的对吧。因为你需要大的尽可能多。用个堆维护就好了

    但是很多人第二种情况想当然了,认为一直取最大值就可以了,但是这种行为太(Naive)了。我们需要讨论一下,如果当前能取的最小值不是前缀最大值,则需要先选他,否则就选能选的最大值,因为你选了这个最小值以后可能释放一个比当前最大值更大的值,这样子答案就可能会更优。那么这个怎么维护呢,用个(set)就好了,如果不会看下代码吧

    (Code)

    #include<bits/stdc++.h>
    #define rg register
    #define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
    using namespace std;
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
        while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
        return f*x;
    }
    struct node {
    	int to,next;
    }a[1000001];
    int head[1000001],cnt,n,m,x,y;
    int vis[1000001];
    int bj[1000001];
    set<int> s;
    priority_queue<int,vector<int>,greater<int> > p;
    void add(int x,int y){
    	a[++cnt].to=y;
    	a[cnt].next=head[x];
    	head[x]=cnt;
    }
    void solve1(){
    	int maxx=0,ans=0;
    	while(!p.empty()){
    		int now=p.top();
    		p.pop();
    		if(now>maxx) maxx=now,ans++;
    		for(int i=head[now];i;i=a[i].next){
    			int v=a[i].to;
    			vis[v]--;
    			if(!vis[v]) p.push(v);
    		}
    	}
    	printf("%d
    ",ans);
    }
    void solve2(){
    	int maxx=0,ans=0;
    	while(!s.empty()){
    		set<int>::iterator it=s.end();it--;
    		set<int>::iterator it2=s.begin();
    		int now1=*it2,now=now1;
    		if(now1>maxx) now=*it;
    		s.erase(now);
    		if(now>maxx) maxx=now,ans++;
    		for(int i=head[now];i;i=a[i].next){
    			int v=a[i].to;
    			bj[v]--;
    			if(!bj[v]) s.insert(v);
    		}
    	}
    	cout<<ans;
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=m;i++)
    		x=read(),y=read(),add(x,y),vis[y]++,bj[y]++;
    	for(int i=1;i<=n;i++)
    		if(!vis[i]) s.insert(i),p.push(i);
    	solve1();
    	solve2();
        return 0;
    }
    
  • 相关阅读:
    python 按行读取判断是否为空
    python获取目录下所有文件
    Kolakoski
    最小背包问题
    python 求第k个最大数
    python 求最大子序列
    爬取数据的程序
    文件对比程序
    trsd_extract_EDSD_new
    tred_extract_EDED_new
  • 原文地址:https://www.cnblogs.com/hbxblog/p/11749582.html
Copyright © 2011-2022 走看看