• POJ2762 Going from u to v or from v to u(单连通 缩点)


    判断图是否单连通,先用强连通分图处理,再拓扑排序,需注意:

    符合要求的不一定是链
    拓扑排序列结果唯一,即在队列中的元素始终只有一个

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<utility>
    #include<stack>
    using namespace std;
    typedef long long LL;
    const int N = 1008, INF = 0x3F3F3F3F;
    int dfn[N],id[N];
    int lab,cnt;
    stack <int> st;
    int n, m;
    int head[N], tot;
    int indeg[N];
    vector<int> g[N];
    void init(){
    	memset(head, - 1,sizeof(head));
    	tot=  0;
    }
    
    struct Edge{
    	int to, next;
    }edge[20008];
    
    void add(int u, int v){
    	edge[tot].to = v;
    	edge[tot].next = head[u];
    	head[u] = tot++;
    }
    
    int dfs(int u){
    	int lowu=dfn[u]=++lab;
    	st.push(u);
        for(int i = head[u];i!=-1;i=edge[i].next){
            int v = edge[i].to;
            if(!dfn[v]){
                int lowv = dfs(v);
                lowu = min(lowu, lowv);
            }else if(!id[v]) {
                lowu = min(lowu, dfn[v]);
            }
        }
        if(lowu == dfn[u]){
            cnt++;
            while(1){
                int x = st.top();
                st.pop();
                id[x] = cnt;
                if(x == u) break;
            }
        }
        return lowu;
    }
    int tarjan(){
        for(int i=1;i<=n;i++) {
            dfn[i] = id[i] = 0;
        }
        lab=cnt=0;
        for(int i=1;i<=n;i++) {
            if(!dfn[i]){
             dfs(i);
            }
        }
        return cnt;
    }
    
    //符合要求的不一定是链
    //拓扑排序列结果唯一,即在队列中的元素始终只有一个
    bool topsort(int n){
        queue<int > q;
        int sum = 0;
        for(int i = 1; i <= n; i++){
            if(indeg[i] == 0){
                q.push(i);
                if(q.size() > 1){
                   return false;
                }
            }
        }
        while(!q.empty()){
            int u = q.front();
            q.pop();
            sum++;
            for(int i= 0; i < g[u].size(); i++){
            	int v = g[u][i];
            	indeg[v]--;
            	if(indeg[v] == 0){
            		q.push(v);
            	}
            }
            if(q.size() > 1){
            	return false;
            }
        }
        if(sum != n){
            return false;
        }
        return true;
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
        	init();
        	memset(indeg, 0, sizeof(indeg));
        	scanf("%d %d", &n, &m);
        	while(m--){
        		int u, v;
        		scanf("%d %d", &u, &v);
        		add(u, v);
        	}
        	tarjan();
        	for(int i =1; i<= cnt; i++){
                g[i].clear();
        	}
        	for(int u = 1; u <= n; u++){
        		for(int i = head[u] ; ~i ; i = edge[i].next){
        			int v = edge[i].to;
        			if(id[u] != id[v]){
        				indeg[id[v]]++;
        				g[id[u]].push_back(id[v]);
        			}
        		}
        	}
        	if(topsort(cnt)){
                printf("Yes
    ");
        	}else{
        		printf("No
    ");
        	}
        }
        return 0;
    }
    

      

  • 相关阅读:
    dijkstra最短路算法--模板
    k8s ansible自动化部署
    k8s persistenvolume 动态供给
    k8s 1.12二进制部署
    k8s 1.14.1 coredns部署
    django单表操作,增、删、改、查
    数据库基础
    TCP/IP协议 socket
    面向对象的程序设计
    模块
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5755681.html
Copyright © 2020-2023  润新知