日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVA - 1218 Perfect Service(树形dp)

發布時間:2023/12/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVA - 1218 Perfect Service(树形dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:UVA - 1218 Perfect Service

題意

有n臺電腦,互相以無根樹的方式連接,現要將其中一部分電腦作為服務器,且要求每臺電腦必須連接且只能連接一臺服務器(不包括作為服務器的電腦),求最少需要多少臺電腦作為服務器。

思路

典型的樹形dp問題,那么我們來建立模型。
d(u,0):u是服務器,孩子是不是服務器均可
d(u,1):u不是服務器,u的父親是服務器,u的孩子不能是服務器
d(u,2):u不是服務器且u的父親不是服務器,u的孩子必須有且僅有一個是服務器。

那么顯然的
d(u,0) = 1 + Sum( Min(d(v,1), d(v,0)) ) |v是u的孩子
d(u,1) = Sum(d(v,2))
d(u,2)稍復雜些,因為只能有一個孩子是服務器,所以需要遍歷每個孩子為服務器的情況,每一輪遍歷都要同時計算其他所有孩子,需要O(N^2)的時間。
顯然這樣會有很多重復計算的情況,當然可以記憶化來加快速度,但是還有一個更快的小技巧,因為d(u,1)和d(u,2)的唯一區別就是d(u,2)的孩子有一個服務器
那么我們可以得出
d(u,2) = Min(d(u,1)-d(v,2)+d(v,0)) |v是u的孩子
仍是遍歷設每個孩子為服務器,每一輪的操作為O(1),總體為O(N)

代碼

ps:因為d(u,2)初始要設為無窮大,就設了0x3f3f3f3f,結果改成N就好了,找了好久才找出問題出在這,因為這個wrong了好多遍,但還是不知道為什么會wrong,知道原因的道友請不吝指點。

第一遍a的代碼

#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <vector> #include <cmath> #include <map>using namespace std;const int N = 10009; vector<int> g[N]; int dp[N][3];void dfs(int u, int fa) {for(int i=0; i<g[u].size(); i++){if(g[u][i] != fa)dfs(g[u][i], u);}dp[u][0] = 1;dp[u][1] = 0;dp[u][2] = N;for(int i=0; i<g[u].size(); i++){if(g[u][i] != fa){dp[u][0] += min(dp[g[u][i]][0], dp[g[u][i]][1]);dp[u][1] += dp[g[u][i]][2];}}bool f = true;for(int i=0; i<g[u].size(); i++){if(g[u][i] != fa){f = false;dp[u][2] = min(dp[u][2], dp[u][1]+dp[g[u][i]][0]-dp[g[u][i]][2]);}} }int main() {int n;while(cin>>n){memset(dp, -1, sizeof(dp));int a, b;for(int i=1; i<n; i++){cin>>a>>b;g[a].push_back(b);g[b].push_back(a);}dfs(1, -1);cout<<min(dp[1][0], dp[1][2])<<endl;cin>>a;if(a == -1)break;for(int i=1; i<=n; i++)g[i].clear();}return 0; }

觀摩大神代碼后進行修改的精簡版

#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cstdlib> #include <vector> #include <cmath> #include <map>using namespace std;const int N = 10009; vector<int> g[N]; int dp[N][3];void dfs(int u, int fa) {dp[u][0] = 1;dp[u][1] = 0;dp[u][2] = N;for(int i=0; i<g[u].size(); i++){if(g[u][i] != fa){dfs(g[u][i], u);dp[u][0] += min(dp[g[u][i]][0], dp[g[u][i]][1]);dp[u][1] += dp[g[u][i]][2];}}for(int i=0; i<g[u].size(); i++){if(g[u][i] != fa)dp[u][2] = min(dp[u][2], dp[u][1]+dp[g[u][i]][0]-dp[g[u][i]][2]);} }int main() {int n;while(cin>>n){int a, b;for(int i=1; i<n; i++){cin>>a>>b;g[a].push_back(b);g[b].push_back(a);}dfs(1, -1);cout<<min(dp[1][0], dp[1][2])<<endl;cin>>a;if(a == -1)break;for(int i=1; i<=n; i++)g[i].clear();}return 0; }

總結

以上是生活随笔為你收集整理的UVA - 1218 Perfect Service(树形dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。