城市環路

題目鏈接:城市環路


顯然如果是樹就很簡單了,現在變成了基環樹,考慮斷掉任意一條邊即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e5+10;
int n,p[N],dp[N][2],vis[N],flag,res,now;	double k;
vector<int> g[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
void dfs(int x,int fa,int k){
	if(x!=k)	dp[x][1]=p[x];
	else	dp[x][1]=-1e9;
	for(auto to:g[x])	if(to!=fa&&!((x==now&&to==k)||(x==k&&to==now))){
		dfs(to,x,k);
		dp[x][0]+=max(dp[to][0],dp[to][1]);
		dp[x][1]+=dp[to][0];
	}
}
void find(int x,int fa){
	if(flag)	return ;
	vis[x]=1;
	for(auto to:g[x])	if(to!=fa){
		if(!vis[to])	find(to,x);
		else{
			if(flag)	return ;
			flag=1;	now=x; dfs(x,x,to);
			res=max(dp[x][0],dp[x][1]);
			memset(dp,0,sizeof dp);
			now=to; dfs(to,to,x);
			res=max(res,max(dp[x][0],dp[x][1]));
			return ;
		}
	}
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++)	scanf("%d",&p[i]);
	for(int i=1,a,b;i<=n;i++)	scanf("%d %d",&a,&b),add(a+1,b+1);
	find(1,1);	cin>>k;
	printf("%.1lf\n",k*res);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章