当前位置:
首页 >
CodeForces - 618D Hamiltonian Spanning Tree(思维+贪心)
发布时间:2024/4/11
67
豆豆
生活随笔
收集整理的这篇文章主要介绍了
CodeForces - 618D Hamiltonian Spanning Tree(思维+贪心)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
题目链接:点击查看
题目大意:首先给出n个点,n*(n-1)/2条边组成的无向图,边的权值为y,现在给出一棵连接n个点的树,树上的权值都是x,现在问如何在每个点只遍历一次的情况下走遍n个点,并使一路上权值最小,输出最小权值
题目分析:因为我们需要将n个点连成一条链,所以所需要遍历的边一定是n-1条边,我们现在要做的就是分析如何让这n-1条边的权值和尽量小
我们可以大致分为两种情况来分析:
我们可以将第二种情况进一步分析,我们可以将n个点分为不同长度的数个区块,每个区块中的点都可以通过一条链到达,那么我们就可以用图上的边来连接每个区块即可
这样说可能还是有点抽象,我们直接具体到某个节点来分析:
根据上面两种情况设计一下dfs求出ans,答案就出来了
代码:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=2e5+100;vector<int>node[N];int ans=0;bool dfs(int u,int f) {int son=2;//子节点数for(auto v:node[u]){if(v==f)continue;if(dfs(v,u)&&son)//若此时节点u的子节点v可以顺上来一条链,并且当前子节点是前两个,那么就可以将节点u和节点v用树边连接 //若此时节点u的子节点v已经是大于等于2的子节点了,就不能通过树边连接节点u和节点v了{son--;ans++;}}return son>0;//如果节点u的子节点数小于等于1,那么就可以顺一条链上去,否则就是情况1,也就是节点u被两个子节点所占用 }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n,x,y;scanf("%d%d%d",&n,&x,&y);for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);node[u].push_back(v);node[v].push_back(u);}if(x>=y){bool flag=true;for(int i=1;i<=n;i++)if(node[i].size()==n-1)//判断菊花图{flag=false;break;}if(flag)printf("%lld\n",1LL*(n-1)*y);elseprintf("%lld\n",1LL*(n-2)*y+x);}else{dfs(1,0);printf("%lld\n",1LL*ans*x+1LL*(n-1-ans)*y);}return 0; }
总结
以上是生活随笔为你收集整理的CodeForces - 618D Hamiltonian Spanning Tree(思维+贪心)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: CodeForces - 353E An
- 下一篇: POJ - 2594 Treasure