CodeForces - 618D Hamiltonian Spanning Tree(思维+贪心)
生活随笔
收集整理的這篇文章主要介紹了
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