• 洛谷P3387缩点


    传送门

    有向图。。

    代码中有两种方法,拓扑排序和记忆化搜索

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define re register
    using namespace std ;
    const int maxn = 1e5 + 4 ;
    
    inline int read () {
    	int f = 1 , x = 0 ;
    	char ch = getchar () ;
    	while(ch > '9' || ch < '0')  {if(ch == '-')  f = -1 ; ch = getchar () ;}
    	while(ch >= '0' && ch <= '9')  {x = (x << 1) +(x << 3) + ch - '0' ; ch = getchar () ;}
    	return x * f; 
    }
    
    int n , m , a[maxn] , u , v , ans ; 
    int head[maxn] , tot , head2[maxn] , tot2 ;
    
    struct Edge {
    	int from , to , next ;
    }edge[maxn << 1] , edge2[maxn] ;
    
    inline void add(int u , int v) {
    	edge[++tot].from = u ;
    	edge[tot].to = v ;
    	edge[tot].next =head[u] ;
    	head[u] = tot ;
    }
    
    inline void add2(int u , int v) {
    	edge2[++tot2].from = u ;
    	edge2[tot2].to = v;
    	edge2[tot2].next = head2[u];
    	head2[u] = tot2;
    }
    
    int stack[maxn] , belong[maxn] , top , cnt , num[maxn] ;
    int low[maxn] , dfn[maxn] , ind , dis[maxn] ;
    bool ins[maxn] ;
    
    inline void tarjan(int x) {
        dfn[x] = low[x] = ++ind;
        stack[++top] = x ;
        ins[x] = true ;
        for(re int i = head[x] ; i; i = edge[i].next) {
            int v = edge[i].to ;
            if(!dfn[v]) {
                tarjan(v) ;
                low[x] = min(low[x] , low[v]);
            }
            if(ins[v]) {
                low[x] = min(low[x] , dfn[v]);
            }
        }
        int k = 0;
        if(dfn[x] == low[x]) {
            ++cnt;
            do{
                k = stack[top];
                top--;
                ins[k] = false;
                num[cnt]++;
                dis[cnt] += a[k];
                belong[k] = cnt;
            }while (k != x); 
        }
    }
    
    queue<int> q;
    int dis2[maxn] , in[maxn] ;
    
    inline int topo() {
        for(re int i = 1 ; i <= cnt ; ++ i) 
        	if(!in[i]) {
        		q.push(i);
        		dis2[i] = dis[i];
        	}
        while(!q.empty()) {
        	int cur = q.front();
        	q.pop() ;
        	for(re int i = head2[cur] ; i ; i = edge2[i].next) {
        		int v = edge2[i].to ;
        		dis2[v] = max(dis2[v] , dis2[cur] + dis[v]) ;
        		in[edge2[i].to]-- ;
        		if(!in[edge2[i].to]) 
        			q.push(edge2[i].to) ;
        	}
        }
        for(re int i = 1 ; i <= n ; ++ i)
        	ans = max(ans , dis2[i]) ;
        return ans;
    }
    
    int main () {
    	n = read () ; m =read() ;
    	for(re int i = 1 ; i <= n ; ++ i) 
    		a[i] = read () ;
    	for(re int i = 1 ; i <= m ; ++ i) {
    		u = read () ; v = read () ;
    		add(u , v) ;
    	}
    	for(re int i = 1 ; i <= n ; ++ i) 
    		if(!dfn[i])  tarjan(i) ;
    	for(re int i = 1 ; i <= tot ; ++ i) {
            if(belong[edge[i].from] != belong[edge[i].to]) {
                add2(belong[edge[i].from] , belong[edge[i].to]) ;
                in[belong[edge[i].to]]++ ;
            }
        }
    	printf("%d
    " , topo()) ;
    	return 0 ;
    }
    
  • 相关阅读:
    IP通信02
    h5网页 微信分享给好友,朋友圈-tp5
    微博常用链接
    Sublime Text3之安裝Emmet及使用技巧
    JS 写入到文件
    PHP之httpRequest
    图片上传预览
    滚动数字时钟
    旋转
    创建JavaScript标准对象--面试经常遇到的问题
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/9931411.html
Copyright © 2020-2023  润新知