现在有一个完全无向图,其中包含N个点,现在给出一棵树,树边的权值为x,其余边的权值为y,现在要求从一个点出发,遍历所有的点,并且需要保证每个点只能经过一次,问路径的最小值。
思路:
①如果x>=y,如果其不是菊花图,结果就一定是(n-1)*y,否则需要一条树边来连通其他部分,那么结果就一定是x+(n-2)*y;
②如果x<y,那么对于每个点都有一个2的限制,那么我们过程Dfs贪心一下就行了。
Ac代码:
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
#define ll __int64
ll cnt;
vector<ll>mp[250000];
ll degree[250000];
int Dfs(int u,int from)
{
int son=2;
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(v==from)continue;
if(Dfs(v,u)&&son>0)
{
son--;
cnt++;
}
}
return son>0;
}
int main()
{
ll n,x,y;
while(~scanf("%I64d%I64d%I64d",&n,&x,&y))
{
memset(degree,0,sizeof(degree));
for(ll i=1;i<=n;i++)mp[i].clear();
for(ll i=0;i<n-1;i++)
{
ll x,y;scanf("%I64d%I64d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
degree[x]++;degree[y]++;
}
if(x>=y)
{
ll flag=0;
for(ll i=1;i<=n;i++)
{
if(degree[i]==n-1)flag=1;
}
if(flag==0)
{
printf("%I64d\n",(n-1)*y);
}
else printf("%I64d\n",x+(n-2)*y);
}
else
{
cnt=0;
Dfs(1,-1);
printf("%I64d\n",cnt*x+(n-1-cnt)*y);
}
}
}