[UVA-1218] Perfect Service(树的最小支配集)
Posted wuliking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[UVA-1218] Perfect Service(树的最小支配集)相关的知识,希望对你有一定的参考价值。
题目链接:https://vjudge.net/problem/UVA-1218
题目大意:给你一棵无向树,让你求树的最小支配集,但是有一个要求是除最小支配集外剩下的任何一个结点不能同时连接支配集中的两个元素
解题报告:采用树形dp,只需将第一种状态的状态转移方程修改为$dp[i][0] = 1+\\sum_ p[u]=i min(dp[u][0],dp[u][2])$
AC代码:
1 #include<vector> 2 #include<cstdio> 3 #include<iostream> 4 #include<cmath> 5 #include<queue> 6 #include<stack> 7 #define numm ch-48 8 #define pd putchar(‘ ‘) 9 #define pn putchar(‘\\n‘) 10 #define pb push_back 11 #define fi first 12 #define se second 13 #define fre1 freopen("1.txt","r",stdin) 14 #define fre2 freopen("2.txt","w",stdout) 15 using namespace std; 16 template <typename T> 17 void read(T &res) 18 bool flag=false;char ch; 19 while(!isdigit(ch=getchar())) (ch==‘-‘)&&(flag=true); 20 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 21 flag&&(res=-res); 22 23 template <typename T> 24 void write(T x) 25 if(x<0) putchar(‘-‘),x=-x; 26 if(x>9) write(x/10); 27 putchar(x%10+‘0‘); 28 29 const int maxn=10010; 30 const int N=1010; 31 const int inf=0x3f3f3f3f; 32 const int INF=0x7fffffff; 33 typedef long long ll; 34 struct node 35 int v,net; 36 e[maxn<<1]; 37 int cnt,n,head[maxn]; 38 int dp[maxn][3]; 39 void add(int u,int v) 40 e[++cnt].v=v; 41 e[cnt].net=head[u]; 42 head[u]=cnt; 43 44 void DP(int u,int p) ///u:当前结点,p:u的父结点 45 bool flag=false; ///标记是否有一个dp[to][0]<=dp[to][1] 46 int sum=0,inc=INF; 47 dp[u][2]=0; ///第三状态,当前结点未被选中 48 dp[u][0]=1; ///第一状态,当前结点被选中,dp[u][0]+1 49 for(int i=head[u];i!=-1;i=e[i].net) 50 int to=e[i].v; 51 if(to==p) continue; ///to必须是u的子节点,不是父节点(由根dp到叶子) 52 DP(to,u); ///dp子节点 53 dp[u][0]+=min(dp[to][0],dp[to][2]); ///回溯,第一状态的转移 54 if(dp[to][0]<=dp[to][1]) ///第二状态的判断 55 flag=true; 56 sum+=dp[to][0]; 57 58 else 59 sum+=dp[to][1]; 60 inc=min(inc,dp[to][0]-dp[to][1]); 61 62 if(dp[to][1]!=INF&&dp[u][2]!=INF) ///第三状态的转移 63 dp[u][2]+=dp[to][1]; 64 else dp[u][2]=INF; ///根据定义dp[u][2]=(dp[to][1]的总和) 65 66 if(!flag&&inc==INF) ///判断当前是不是叶子结点 67 dp[u][1]=INF; 68 else 69 dp[u][1]=sum+(flag?0:inc); 70 71 int main() 72 73 while(scanf("%d",&n)!=EOF&&n) 74 for(int i=1;i<=n;i++) 75 head[i]=-1,dp[i][0]=dp[i][1]=dp[i][2]=0,cnt=0; 76 for(int i=1;i<=n-1;i++) 77 int a,b; 78 read(a),read(b); 79 add(a,b); 80 add(b,a); 81 82 DP(1,1); 83 write(min(dp[1][0],dp[1][1]));pn; 84 int flag; 85 read(flag); 86 if(flag==-1) break; 87 88 return 0; 89
以上是关于[UVA-1218] Perfect Service(树的最小支配集)的主要内容,如果未能解决你的问题,请参考以下文章
Perfect Service UVA - 1218(树形dp)
UVA - 1218 Perfect Service(树形dp)
[UVA-1218] Perfect Service(树的最小支配集)
UVA-1220-Party at Hali-Bula && UVA-1218-Perfect Service(树形DP)