• CF1062F Upgrading Cities


    http://codeforces.com/problemset/problem/1062/F

    题解

    有意思的题。

    首先考虑在(DAG)上拓扑的过程,设当前队列中的点集为(S),那么有结论是这些点之间都不能互相到达,这个比较好理解。

    那么我们考虑在弹出一个点的时候计算它能够到达多少点,如果当前队列里有超过一个点,那它肯定就不行了。

    如果一个点都没有,那么剩下的点他都可以访问。

    如果只有一个点,那么看一下那个点的所有出点,如果有一个点的入度为1,说明当前这个点一定不能到达,否则一定全都能到达,这个可以手画理解一下。

    但是还要计算它被多少点到达,这个反着拓扑一下就好了。

    代码

    #include<bits/stdc++.h>
    #define N 300009
    using namespace std;
    typedef long long ll;
    queue<int>q;
    int n,m,du1[N],du2[N],ans,f[N];
    inline ll rd(){
    	ll x=0;char c=getchar();bool f=0;
    	while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f?-x:x;
    }
    std::vector<int>vec1[N],vec2[N];
    std::vector<int>::iterator it;
    inline void add(int u,int v){
    	vec1[u].push_back(v);du1[v]++;
    	vec2[v].push_back(u);du2[u]++;
    }
    int main(){
    	n=rd();m=rd();
    	for(int i=1;i<=n;++i)f[i]=1;
    	int u,v;
    	for(int i=1;i<=m;++i){
    		u=rd();v=rd();
    		add(u,v);
    	}
    	int now=n;
        for(int i=1;i<=n;++i)if(!du1[i])q.push(i),now--;
        while(!q.empty()){
        	int u=q.front();q.pop();
        	if(!q.size())f[u]+=now;
        	else if(q.size()==1){
        		int v=q.front(),o=0;
        		for(it=vec1[v].begin();it!=vec1[v].end();++it){
        			int w=*it;
        			if(du1[w]==1){o=1;break;}
        		}
        		if(!o)f[u]+=now;
        	}
        	for(it=vec1[u].begin();it!=vec1[u].end();++it){
        		int v=*it;
        		if(!--du1[v])q.push(v),now--;
        	}
        }
        now=n;
        for(int i=1;i<=n;++i)if(!du2[i])q.push(i),now--;
        while(!q.empty()){
        	int u=q.front();q.pop();
            if(!q.size())f[u]+=now;
        	else if(q.size()==1){
        		int v=q.front(),o=0;
        		for(it=vec2[v].begin();it!=vec2[v].end();++it){
        			int w=*it;
        			if(du2[w]==1){o=1;break;}
        		}
        		if(!o)f[u]+=now;
        	}
        	for(it=vec2[u].begin();it!=vec2[u].end();++it){
        		int v=*it;
        		if(!--du2[v])q.push(v),now--;
        	}
        }
        for(int i=1;i<=n;++i){
          if(f[i]>=n-1)ans++;
        }
        cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    es集群的调优2
    es集群中kibana和es集群的高可用设置
    es集群中参数参数discovery.zen.minimum_master_nodes深度解析
    哔哩哔哩适合后端编程人员的elasticsearch快速实战教程学习总结
    Vue2-基本语句
    SpringBoot-ElasticSearch初使用
    Java-SSO单点登录的3种方式【待完善】
    Java-学习日记(函数式编程与@ControllerAdvice)
    SpringBoot-内置Tomcat启动原理
    Java-学习日记(Atomic,Volatile)
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/11032046.html
Copyright © 2020-2023  润新知