POJ 3659 Cell Phone Network【最小支配集】
2012-08-06 10:03
274 查看
题意:有以个 有 N 个节点的树形地图,问在这些顶点上最少建多少个电话杆,可以使得所有顶点被覆盖到,一个节点如果建立了电话杆,那么和它直接相连的顶点也会被覆盖到。
分析:用最少的点覆盖所有的点,即为求最少支配集。 可以用树形DP。
① dp[r][0] += min(dp[i][0],dp[i][1],dp[i][2]) dp[r][0]表示在自 r 顶点自身建, 以 r 为根节点的树所需要的最少覆盖数。
② dp[r][1] += min(dp[i][0],dp[i][1]) dp[r][1]表示在r 的子节点建, 以 r 为根节点的树所需要的最少覆盖数。
③ dp[r][2] += min(dp[i][0],dp[i][1]) dp[r][2]表示在r 的父节点建, 以 r 为根节点的数所需要的最少覆盖数。
其中第 ② 个有 特殊情况需要考虑,即如果每次 min () 取得都是dp[i][1]的话,即 r 所有的子节点的都没有建电话杆的话,这样得出的结果就会有误差,可以在其中记录最小
的dp[i][0] 值和其对应的 dp[i][1] 值,最后在这个 i 上建电话杆,就能保证自己被覆盖到,且用的电话杆最少, 这时dp[r][1]+=dp[i][0]-dp[i][1] 即可。
分析:用最少的点覆盖所有的点,即为求最少支配集。 可以用树形DP。
① dp[r][0] += min(dp[i][0],dp[i][1],dp[i][2]) dp[r][0]表示在自 r 顶点自身建, 以 r 为根节点的树所需要的最少覆盖数。
② dp[r][1] += min(dp[i][0],dp[i][1]) dp[r][1]表示在r 的子节点建, 以 r 为根节点的树所需要的最少覆盖数。
③ dp[r][2] += min(dp[i][0],dp[i][1]) dp[r][2]表示在r 的父节点建, 以 r 为根节点的数所需要的最少覆盖数。
其中第 ② 个有 特殊情况需要考虑,即如果每次 min () 取得都是dp[i][1]的话,即 r 所有的子节点的都没有建电话杆的话,这样得出的结果就会有误差,可以在其中记录最小
的dp[i][0] 值和其对应的 dp[i][1] 值,最后在这个 i 上建电话杆,就能保证自己被覆盖到,且用的电话杆最少, 这时dp[r][1]+=dp[i][0]-dp[i][1] 即可。
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) int min(int a,int b) { return a<b?a:b; } #define maxn 100005 #define INF 0x1f1f1f1f struct node { int to; int next; }e[1000000]; int tot; int head[maxn]; int dp[maxn][3]; void add(int s,int u) { e[tot].to=u; e[tot].next=head[s]; head[s]=tot++; } // dp[r][0] = min(dp[i][0],dp[i][1],dp[i][2])自身建 // dp[r][1] = min(dp[i][0],dp[i][1]) 子节点建 // dp[r][2] = min(dp[i][0],dp[i][1]) 父节点建 int n; int v[maxn]; void dfs(int r) { v[r]=1; int i,k; int flag=1,ff=1,mi=INF,t; dp[r][0]=1; for(i=head[r];i;i=e[i].next) { k=e[i].to; if(!v[k]) { flag=0; dfs(k); dp[r][0]+=min(dp[k][0],min(dp[k][1],dp[k][2])); if(dp[k][1]>=dp[k][0]) { ff=0; dp[r][1]+=dp[k][0]; } else { dp[r][1]+=dp[k][1]; if(dp[k][0]<mi) { mi=dp[k][0]; t=dp[k][1]; } } dp[r][2]+=min(dp[k][0],dp[k][1]); } } if(ff) dp[r][1]+=mi-t; if(flag) { dp[r][0]=1; dp[r][1]=INF; dp[r][2]=0; } } int main() { int a,b,i; while(scanf("%d",&n)!=EOF) { tot=1; clr(v); clr(dp); clr(head); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } if(n==1) { printf("1\n"); continue; } dfs(1); printf("%d\n",min(dp[1][0],dp[1][1])); } return 0; }
相关文章推荐
- POJ 3659 Cell Phone Network(树的最小支配集)(贪心)
- poj3659 Cell Phone Network(最小支配集-树形dp)
- POJ - 3659 Cell Phone Network 最小支配集(树的) 贪心算法
- POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法
- poj 3659 Cell Phone Network(树dp+树的最小支配集)
- POJ 3659 Cell Phone Network【最小支配集、树型dp】
- poj 3659 Cell Phone Network(树的最小支配集树形DP)
- POJ 3659 Cell Phone Network【最小支配集 dp && 贪心】
- poj 3659 Cell Phone Network (树最小支配集)
- POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-贪心做法
- Poj 3659 Cell Phone Network(树的最小支配集)
- poj 3659 Cell Phone Network 树型DP也是树的最小支配集
- 【POJ】3659 Cell Phone Network 树上的极小支配集——树型DP
- POJ 3659 Cell Phone Network 最小支配集
- poj 3659 Cell Phone Network 树的最小点支配集
- POJ 3659 Cell Phone Network(树形DP)
- poj 3659 Cell Phone Network USACO 树形DP
- 【POJ3659】【USACO 2008 Jan Gold】 3.Cell Phone Network 树上最小支配集/贪心 两种做法
- 【POJ 3659】Cell Phone Network
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)