骑士代码改的基环树+舞会,但只过了第二个点,其他的全部MLE,hack数据全部WA
#include<bits/stdc++.h>
#define AC return 0;
#define sc(n) scanf("%d",&(n))
#define pr(n) printf("%lld",(n))
#define hh puts("")
#define kg printf(" ")
using namespace std;
namespace fr{
int read()
{
int x=0,flag=1;
char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar())if(ch=='-')flag=-1;
for(;ch<='9'&&ch>='0';ch=getchar())x=(x<<3)+(x<<1)+ch-'0';
return flag*x;
}
}
using namespace fr;
const int N= 1e5+6;
int a[N],h[N];
int f[N][2];
vector<int> g[N];
bool vis[N];
int root,ans;
double k;
void dance(int now)
{
vis[now]=1;
f[now][0]=0,f[now][1]=a[now];
for(auto v:g[now])
{
if(v!=root)
{
dance(v);
f[now][0]+=max(f[v][0],f[v][1]);
f[now][1]+=f[v][0];
}
else
f[v][1]=-114514191;
}
}
void find_circle(int now)
{
vis[now]=1;
root=now;
while(!vis[h[root]])
{
root=h[root];
vis[root]=1;
}
dance(root);
int res=max(f[root][0],f[root][1]);
vis[root]=1;
root=h[root];
dance(root);
ans+=max(res,max(f[root][0],f[root][1]));
}
signed main()
{
int n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
}
for(int i=1;i<=n;i++)
{
int u=read()+1;h[u]=read()+1;
g[h[u]].push_back(u);
}
scanf("%lf",&k);
for(int i=1;i<=n;i++)if(!vis[i])find_circle(i);
printf("%.1f",ans*k);
AC
}