zoukankan      html  css  js  c++  java
  • POJ 1236 Network of Schools(tarjan)题解

    题意:一个有向图。第一问:最少给几个点信息能让所有点都收到信息。第二问:最少加几个边能实现在任意点放信息就能传遍所有点

    思路:把所有强连通分量缩成一点,然后判断各个点的入度和出度

    tarjan算法:问问神奇海螺啥是tarjan

    代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<queue>
    #include<cmath>
    #include<string>
    #include<map>
    #include<stack> 
    #include<set>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #define INF 0x3f3f3f3f
    const int N=110;
    const int MOD=1000; 
    using namespace std;
    int n,index,scc_cnt;	//scc_cnt记录SCC 
    int dfn[N],low[N],sccno[N],in[N],out[N];
    vector<int> g[N];
    stack<int> s;
    void tarjan(int x){
    	int i;
    	dfn[x]=low[x]=++index;
    	s.push(x);
    	for(i=0;i<g[x].size();i++){
    		int v=g[x][i];
    		if(!dfn[v]){	//未走过 
    			tarjan(v);
    			low[x]=min(low[x],low[v]);
    		}
    		else if(!sccno[v]){	//走过且在栈中 
    			low[x]=min(low[x],dfn[v]);
    		}
    	}
    	if(dfn[x]==low[x]){
    		scc_cnt++;	//增加一个大点  
    		int a;
    		while(1){	//x及以后全部出栈 
    			a=s.top();
    			s.pop();
    			sccno[a]=scc_cnt;
    			if(a==x) break;
    		}
    	}
    }
    void done(){
    	index=scc_cnt=0;
    	memset(dfn,0,sizeof(dfn));
    	memset(sccno,0,sizeof(sccno));
    	for(int i=0;i<n;i++){
    		if(!dfn[i]) tarjan(i);
    	}
    }
    int main(){
    	int t;
    	while(~scanf("%d",&n) && n){
    		for(int i=0;i<n;i++) g[i].clear();
    		for(int u=0;u<n;u++){
    			while(~scanf("%d",&t) && t){
    				t--;
    				g[u].push_back(t);
    			}
    		}
    		done();
    		int ans1,ans2;
    		for(int i=1;i<=scc_cnt;i++){
    			in[i]=out[i]=0;	//入度出度初始化为无 
    		}
    		for(int i=0;i<n;i++){
    			for(int j=0;j<g[i].size();j++){
    				int v=g[i][j];
    				if(sccno[i]!=sccno[v]){
    					in[sccno[v]]=out[sccno[i]]=1;	//一个有入度一个有出度 
    				}
    			}
    		}
    		ans1=ans2=0;
    		for(int i=1;i<=scc_cnt;i++){
    			if(in[i]==0) ans1++;
    			if(out[i]==0) ans2++;
    		}
    		if(scc_cnt==1) printf("1
    0
    ");
    		else printf("%d
    %d
    ",ans1,max(ans1,ans2));
    	}
    	return 0;
    }

  • 相关阅读:
    RTB
    urllib.error.HTTPError: HTTP Error 403: Forbidden
    HTTP请求过程详解
    python中用filter求素数
    python把str转换为int
    如何判断一个GPS点是否在以另一个GPS点为圆心100米为半径的圆内(Java代码)
    word2010表格中的内容怎么设置行距
    java创建二叉树并实现非递归中序遍历二叉树
    java创建二叉树并递归遍历二叉树
    极客DIY:打造属于自己的无线移动渗透测试箱
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9409121.html
Copyright © 2011-2022 走看看