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;
    }
    
  • 相关阅读:
    liunx知识点滴积累(1)
    Regsvr32命令的使用
    QTP知识点滴积累
    LoadRunner的Apache的监控
    CMM和过程改进的“妙语” 集锦
    Linux 性能调优的几种方法
    数据库学习笔录(转载)
    Windows性能管理解析
    使用NUnit在.Net编程中进行单元测试
    Google 工程师文化 互助篇
  • 原文地址:https://www.cnblogs.com/bzzs/p/13697019.html
Copyright © 2011-2022 走看看