1317: Find the max Link
Time Limit: 1 Sec Memory Limit: 128 MB[ Submit][ Status][ Web Board]
Description
由N个点组成的无向图,每条边有对应的权值,保证每两点之间存在且仅存在一条路径,一条路径的权值为其所有边的权值之和,请找出一条路径,对于图中每个点至多经过一次,并且这条路径上至少有一条边,这条路径的权值最大。
Input
多组数据(至多30组),第一行两个正整数N,M(2<=N<=50000,1<=M<=50000),接下来M行,每行三个整数U,V,W(1<=U,V<=N,-100000<=W<=100000)代表在点V,W间有一条权值为W的边。
Output
每组数据输出一行,为一个整数即满足题目要求的路径权值。
Sample Input
4 33 1 -14 2 42 1 5
Sample Output
9
树形DP
d[i][0]表示在i为根的子树中,以i为起点的拥有最大权的路径权值
d[i][0]表示在i为根的子树中,以i为起点的拥有第二大权的路径权值
树形DP
d[i][0]表示在i为根的子树中,以i为起点的拥有最大权的路径权值
d[i][0]表示在i为根的子树中,以i为起点的拥有第二大权的路径权值
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 50011
#define INF -10000000
struct Node {
long long son;
long long w;
};
long long ans;
vector<Node> num[maxn];
long long d[maxn][2];
void DFS(long long x,long long p)
{
long long i,v;
d[x][0]=d[x][1]=INF;
for(i=0;i<num[x].size();i++)
{
v=num[x][i].son;
if(v!=p)
{
DFS(v,x);
if(d[v][0]>0)
{
if(d[x][0]<num[x][i].w+d[v][0])
{
d[x][1]=d[x][0];
d[x][0]=num[x][i].w+d[v][0];
}
else if(d[x][1]<num[x][i].w+d[v][0])
d[x][1]=num[x][i].w+d[v][0];
}
else
{
if(d[x][0]<num[x][i].w)
{
d[x][1]=d[x][0];
d[x][0]=num[x][i].w;
}
else if(d[x][1]<num[x][i].w)
d[x][1]=num[x][i].w;
}
}
}
ans=max(ans,d[x][0]);
ans=max(ans,d[x][0]+d[x][1]);
}
int main()
{
long long N,M;
long long i,u,v;
long long w;
Node tmp;
while(scanf("%lld%lld",&N,&M)==2)
{
for(i=1;i<=N;i++)
num[i].clear();
ans=-10000000;
for(i=1;i<=M;i++)
{
scanf("%lld%lld%lld",&u,&v,&w);
tmp.w=w;
tmp.son=v; num[u].push_back(tmp);
tmp.son=u; num[v].push_back(tmp);
ans=max(ans,w);
}
DFS(1,-1);
printf("%lld\n",ans);
}
return 0;
}