zoukankan      html  css  js  c++  java
  • BZOJ 2438: [中山市选2011]杀人游戏

    Description

    给你一个有向图,求至少询问多少次能够得到全部点的信息.

    Sol

    Tarjan + 强连通分量缩点 + 判断.

    先缩点,如果我们知道了强连通分量里的任意一个点,我们就可以知道这些点的信息,和这些点所连接的其他点的信息,显然我们需要知道的就是缩点后入度为0的点.

    然后还有最后一个入度为0的单点,并且他的所有儿子都能被其他节点访问,那么最后就可以直接推断出这个点,所以要删去.

    Code

    #include<cstdio>
    #include<stack>
    #include<vector>
    #include<iostream>
    using namespace std;
    
    const int N = 100005;
    #define debug(a) cout<<#a<<"="<<a<<" "
    #define ct cout<<endl
    #define _ct cout<<"----------"<<endl
    
    int n,m,cnt,bcnt;
    int dfsn[N],low[N],ins[N],b[N],sz[N],vis[N];
    vector<int> g[N];
    vector<int> h[N];
    int du[N];
    stack<int> stk;
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; }
    void Tarjan(int u){
    	dfsn[u]=low[u]=++cnt,ins[u]=1,stk.push(u);
    	for(int i=0,lim=g[u].size(),v;i<lim;i++){
    		v=g[u][i];
    		if(!dfsn[v]){ Tarjan(v),low[u]=min(low[u],low[v]); }
    		else if(ins[v]) low[u]=min(low[u],dfsn[v]);
    	}if(dfsn[u]==low[u]){
    		++bcnt;int v=-1;
    		for(;u!=v;){ v=stk.top(),stk.pop(),ins[v]=0,b[v]=bcnt,sz[bcnt]++; }
    	}
    }
    int check(int x){
    	for(int i=0,lim=h[x].size();i<lim;i++) if(du[h[x][i]]<=1) return 0;
    	return 1;
    }
    int main(){
    //	freopen("in.in","r",stdin);
    	n=in(),m=in();
    	for(int i=1,u,v;i<=m;i++) u=in(),v=in(),g[u].push_back(v);
    	for(int i=1;i<=n;i++) if(!dfsn[i]) Tarjan(i);
    //	_ct;debug(bcnt),ct;
    	for(int i=1;i<=n;i++){
    		for(int j=0,lim=g[i].size();j<lim;j++) if(b[i]!=b[g[i][j]]&&!vis[b[g[i][j]]]) 
    			vis[b[g[i][j]]]=1,h[b[i]].push_back(b[g[i][j]]),du[b[g[i][j]]]++;
    		for(int j=0,lim=g[i].size();j<lim;j++) if(b[i]!=b[g[i][j]]) vis[b[g[i][j]]]=0;
    	}
    //	_ct;
    	int ans=0;
    	for(int i=1;i<=bcnt;i++) if(du[i]==0) ans++;
    	for(int i=1;i<=bcnt;i++) if(du[i]==0&&sz[i]==1&&check(i)){ ans--;break; }
    //	debug(ans),ct;
    	printf("%.6lf
    ",(double)(n-ans)/n);
    	return 0;
    }
    

      

  • 相关阅读:
    jenkins(5): jenkins邮件报警配置
    Hive(二)—— 架构设计
    Flume(三) —— 断点续传 与 事务
    Flume(二) —— 自定义拦截器、Source、Sink
    Canal —— 基本概念及使用
    Kafka(五) —— Kafka源码本地调试
    Hadoop(五)—— HDFS NameNode、DataNode工作机制
    Cloudera-Manage —— 基本概念及使用
    【系统设计&解决方案】秒杀系统设计
    HBase(一) —— 基本概念及使用
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/5928789.html
Copyright © 2011-2022 走看看