这题面又有毒、、
题目不清楚、而且它好像还用三行文字解释了一个三元环、、
然后图不就是这样(强迫症勿看)?:
然后由于交点只有一个、所以直接子树dp、
注意对环处理一定是从子树根节点判断环处理、不然会更新不上,1WA
码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 200005
int hou[N<<1],xia[N],zhong[N<<1],tot,ans,x,y,d[N],a[N],v[N],n,m,fu[N],cnt,g[N][3],f[N][3];
bool vis[N];
void jian(int a,int b)
{
++tot,hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b;
}
void jia(int a,int b)
{
jian(a,b);
jian(b,a);
}
void dp(int o,int oo)
{
int i,j;
cnt=0;
for(i=oo;i!=o;i=fu[i])
a[++cnt]=i,g[i][1]=f[i][1],g[i][0]=f[i][0];
a[++cnt]=o;g[o][1]=f[o][1],g[o][0]=f[o][0];
//o是不选的
for(i=2;i<=cnt-1;i++)
{
int x=a[i],y=a[i-1];
g[x][0]+=max(g[y][0],g[y][1]);
g[x][1]+=g[y][0];
}
f[o][0]+=max(g[a[cnt-1]][0],g[a[cnt-1]][1]);
for(i=1;i<=cnt;i++)
g[a[i]][0]=f[a[i]][0],g[a[i]][1]=f[a[i]][1];
for(i=2;i<=cnt-1;i++)
{
int x=a[i],y=a[i-1];
if(i==2)
{
g[x][0]+=g[y][0];
g[x][1]+=g[y][0];
continue;
}
g[x][0]+=max(g[y][0],g[y][1]);
g[x][1]+=g[y][0];
}
f[o][1]+=g[a[cnt-1]][0];
}
void dfs(int o,int fa,int dis)
{
int i,j;
d[o]=dis;
f[o][1]=v[o];
fu[o]=fa;
vis[o]=1;
for(i=xia[o];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(nd==fa||vis[nd])continue;
dfs(nd,o,dis+1);
}
for(i=xia[o];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(fu[nd]!=o&&d[nd]>d[o])dp(o,nd);
}
}
int main()
{
int x,y,i;
memset(xia,-1,sizeof(xia));
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
jia(x,y);
}
for(i=1;i<=n;i++)scanf("%d",&v[i]);
dfs(1,0,1);
ans=max(f[1][0],f[1][1]);
printf("%d",ans);
}