1 2 3 4

牛客S2第9场 - 钻石&王者 最大可能的直径

https://ac.nowcoder.com/acm/contest/9977/C

这题让找基环树删除环上一边之后最大的直径

我枚举删除环上的边写的,很暴力,希望路过的大佬告诉我更加高效的写法

#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 5e3+111;
vector<int>G[maxn];
void add(int x,int y){
	G[x].push_back(y);
} 
int dp[maxn]; 
int ans;
int n;

int mp[maxn][maxn];


int dfs(int x,int fa){
	dp[x] = 1;
	int mx = -1;	
	for(int i=0;i<G[x].size();i++){
		int p  = G[x][i];
		if(p == fa || mp[x][p]) continue;
		
		dfs(p,x);
		dp[x] = max(dp[p] + 1,dp[x]);
		if(mx == -1) mx = dp[p];
		else{
			ans = max(dp[p] + mx + 1,ans);
			mx = max(dp[p],mx);
		} 
	}
	return 0;
}
int vis[maxn];
vector<int>ins;
stack<int>s;

int tarjan(int x,int fa){
	if(vis[x]) {
		if(ins.size() != 0) return 0;
		ins.push_back(x);
		while(s.size()){
			int a = s.top();
			s.pop();
			ins.push_back(a);
			if(a == x) break;
		}
		return 0;
	}	
	
	s.push(x);
	vis[x] = 1;
	
	for(int i=0;i<G[x].size();i++){
		int p  = G[x][i];
		if(p == fa) continue;
		tarjan(p,x);
	}
	if(s.size()) s.pop();
	
	return 0;
}




class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param n int整型 
     * @param u int整型vector 
     * @param v int整型vector 
     * @return int整型
     */
    int MaxDiameter(int m, vector<int>& u, vector<int>& v) {
        // write code here
        n = m;
        
        for(int i=0;i<u.size();i++){
        	int x = u[i];
        	int y = v[i];
        	add(x,y);
        	add(y,x);
		}
		tarjan(1,0);
		
		for(int i=1;i<ins.size();i++){
			int x = ins[i-1];
			int y = ins[i];
			mp[x][y] = 1;
			mp[y][x] = 1;
			dfs(1,-1);
			mp[x][y] = 0;
			mp[y][x] = 0;
		}
		
		return ans-1;
    }
    
};

  

posted @ 2020-12-15 21:55  Lesning  阅读(78)  评论(0编辑  收藏  举报