zoukankan      html  css  js  c++  java
  • 洛谷 P4742 【[Wind Festival]Running In The Sky】

    tarjan模板题


    这道题tarjan加记忆化搜索就行,记忆化搜索中,就可以完美解决最大值和最长路。直接讲比较抽象,上代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n , m , now , tot , ans1 , ans2;
    int dfn[200010] , low[200010] , home[200010] , a[200010] , dis[200010] , vis[200010] , kp[200010];
    int f[200010] , maxx[200010];
    stack<int> s;
    vector<int> e[200010];
    vector<int> ne[200010];	//存重建的图 
    void tarjan(int x){
    	dfn[x] = low[x] = ++now;
    	s.push(x);
    	vis[x] = 1;
    	for(int i = 0; i < e[x].size(); i++){
    		int nx = e[x][i];
    		if(!dfn[nx]){
    			tarjan(nx);
    			low[x] = min(low[x] , low[nx]);
    		}else if(vis[nx]) low[x] = min(low[x] , dfn[nx]); 
    	}
    	if(dfn[x] == low[x]){
    		tot++;
    		while(!s.empty()){
    			int top = s.top();
    			s.pop();
    			kp[tot] = max(kp[tot] , a[top]);	//统计下最大值 
    			vis[top] = 0;
    			dis[tot] += a[top];	//统计点的和 
    			home[top] = tot;
    			if(top == x) break;
    		}
    	}
    }
    void dfs(int x){
    	if(f[x]) return;
    	f[x] = dis[x];
    	int ans = 0 , ansmax = 0;
    	for(int i = 0; i < ne[x].size(); i++){
    		int nx = ne[x][i];
    		dfs(nx);
    		if(f[nx] > ans){	//最长路优先,其次最大值 
    			ans = f[nx];
    			ansmax = maxx[nx];
    		}else if(f[nx] == ans){
    			if(maxx[nx] > ansmax) ansmax = maxx[nx];
    		}
    	}
    	f[x] += ans;	//选择最长路 
    	maxx[x] = max(ansmax , kp[x]);
    }
    int main(){
    	cin >> n >> m;
    	for(int i = 1; i <= n; i++) cin >> a[i];
    	for(int i = 1; i <= m; i++){
    		int x , y;
    		cin >> x >> y;
    		e[x].push_back(y);
    	}
    	for(int i = 1; i <= n; i++)
    		if(!dfn[i]) tarjan(i);
    	for(int i = 1; i <= n; i++)
    		for(int j = 0; j < e[i].size(); j++){	//重建 
    			int nx = e[i][j];
    			if(home[nx] != home[i]) ne[home[i]].push_back(home[nx]);
    		}
    	for(int i = 1; i <= tot; i++) dfs(i);	//记忆化搜索 
    	for(int i = 1; i <= tot; i++)	//枚举答案 
    		if(f[i] > ans1){
    			ans1 = f[i];
    			ans2 = maxx[i];
    		}else if(f[i] == ans1){
    			if(maxx[i] > ans2) ans2 = maxx[i];
    		}
    	cout << ans1 << " " << ans2;
    	return 0;
    }
    
  • 相关阅读:
    12.精益敏捷项目管理——产品协调小组笔记
    打字游戏
    提升权限
    下载者
    SMTP实现发送邮箱2(封装版)
    SMTP实现发送邮箱1
    电子邮件协议详解
    JSON运用在文件
    JSON函数表2
    JSON函数表1
  • 原文地址:https://www.cnblogs.com/bzzs/p/13697019.html
Copyright © 2011-2022 走看看