标签:uva 10859 placing lampposts 树形dp
// uva 10859 Placing Lampposts // 树形dp // // 题目的意思是一个无向无环图中,有一些顶点和一些边 // 要在顶点上放置灯笼(灯笼可以照亮与它相邻接的点), // 使得所有的边都能被灯笼照亮,其中可能有一些边被两个灯笼 // 照亮,则要求使得所有边都被灯笼照亮所需灯笼的最小值, // 并且,此时边同时被两个灯笼照亮的数目应尽可能的多 // // 思路是 // d[i][0]表示在节点i不放置灯笼所需的灯笼的最小值 // d[i][1]表示在节点i放置灯笼所需的灯笼的最小值 // // 先说明一下一下j表示i的子节点 // // // 则状态转移方程为 // d[i][0] += d[j][1];(这条路必须要被照亮) // d[i][1] += max(d[j][1],d[j][0]) // // 再定义一个f // f[i][0]表示节点i放置灯笼边同时被两个灯笼照亮的总数最大值 // f[i][1]表示节点i放置灯笼边同时被两个灯笼照亮的总数最大值 // // 则状态转移可能有点复杂 // 如下所示: // 首先f数组肯定要根据d数组来递推 // // f[i][0] += f[j][1] (没得选,i到j必须被照亮) // // f[i][1] 应该首先根据d[j][0] 和 d[j][1] 来 // 如果后面的两者不相等,则取较小的第二维记作mk(保证总的灯笼最小) // 此时f[i][1] += f[j][mk] + mk ? 1 : 0; (如果mk==1则i到j的边被两个灯笼 // 照亮,即加一) // // 如果d[j][0] == d[j][1]; // // 则此时f[i][1] += max(f[j][0],f[j][1] + 1)(在i放灯笼的情况下,j放不放灯笼 // 所需的灯笼的总数都是一样的,那么就看j放灯笼的 f[j][1]+1 大 // 还是不放灯笼的f[j][0]大) // // 至此,这道题目算是思路很清楚了。另外就是要注意图可能是不连通的 // // 下面说说这题给我带来的感受。以及自身的一丝变化。 // // 这一题是我真真正正自己想出来,并努力自己做出来的题目。看到mw给我看的一组 // ACM前辈的问答:为什么当初我们是一个水平,但是后来你进了final,我却没有 // 回答是:我在有了一定的基础之后就不看解题报告了。这句话给我一直很大的冲击 // 如果是刚入门的时候,你看看题解,没人会说你什么,因为都是菜鸟,看看题解, // 入门会快一些,也会多一些经验,在入了门以后,再看题解,也没人会说什么,自 // 己会清楚自己的状态,如果你认为看题解对你有帮助,那就看呗,如果不是为自己 // 毫无意义的虚荣心的话。 // // 虽然我以前经常在无助的时候看题解,也并不明白为什么是这样,所以我反复的提 // 交,反复的看,反复的提交,在自己不明白的地方就加上自己理解的代码再提交。 // 虽然当时真的感觉自己吃透这一题了,但是在过了不久之后再看到这一题的时候还 // 是感觉像是新的题目一样。如果你大多数都是看题解的话,建议你把以前的题目在 // 做一遍,如果没有我这样的感受,我只能在这里膜拜一发各位巨巨。但对于我来说 // 就是这样。 // // 这道题目其实训练指南上有详细的解题指导,我也看了,但是完全看不懂在讲什么 // 在自己卡了两天,wrong answer 了好久之后,这段时间我真的是忍不住差点跟着 // 书上的思路敲一遍算了的想法出现,但最终我还是忍住了,一遍一遍的调试,最后 // 的结果还是挺让人高兴的。那种accept的感受不是简单的过了的感受,而是自己的 // 成果最终是有回报的。在此,我要感谢mw,是他点醒了我,会求一个值,就会求 // 第二个值。猛然醒悟。 // 虽然这题仔细想来并不是很难,但这是 // 我感受到了自己的喜悦,不多说,继续努力,付出总会有回报。fighting // #include <algorithm> #include <bitset> #include <cassert> #include <cctype> #include <cfloat> #include <climits> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <functional> #include <iostream> #include <list> #include <map> #include <numeric> #include <queue> #include <set> #include <stack> #include <vector> #define ceil(a,b) (((a)+(b)-1)/(b)) #define endl '\n' #define gcd __gcd #define highBit(x) (1ULL<<(63-__builtin_clzll(x))) #define popCount __builtin_popcountll typedef long long ll; using namespace std; const int MOD = 1000000007; const long double PI = acos(-1.L); template<class T> inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; } template<class T> inline T lowBit(const T& x) { return x&-x; } template<class T> inline T maximize(T& a, const T& b) { return a=a<b?b:a; } template<class T> inline T minimize(T& a, const T& b) { return a=a<b?a:b; } const int maxn = 1008; int head[maxn]; struct node{ int to; int next; }edges[maxn*2]; int num; int n,m; int f[maxn][2]; int d[maxn][2]; bool vis[maxn]; void add_edges(int u,int v){ edges[num].to = v; edges[num].next = head[u]; head[u] = num++; } void init(){ memset(f,0,sizeof(f)); memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); num=0; scanf("%d%d",&n,&m); for (int i=1;i<=m;i++){ int u,v; scanf("%d%d",&u,&v); add_edges(u,v); add_edges(v,u); } } void dfs(int u,int fa){ d[u][0] = 0; d[u][1] = 1; vis[u] = true; for (int i=head[u];i!=-1;i=edges[i].next){ int v = edges[i].to; if (!vis[v]){ dfs(v,u); d[u][0] += d[v][1]; int mk = -1; if (d[v][0] < d[v][1]){ mk = 0; }else { mk = 1; } d[u][1] += d[v][mk]; int temp = 0; temp = f[v][mk] + (mk?1:0); if (d[v][1]==d[v][0]) temp = max(temp,max(f[v][1]+1,f[v][0])); f[u][1] += temp; //d[u][1] += min(d[v][0],d[v][1]); f[u][0] += f[v][1]; } } } void print(){ for (int i=0;i<n;i++){ printf("%d %d\n",f[i][0],f[i][1]); } } void solve(){ int sum = 0; int mx = 0; for (int i=0;i<n;i++) if (!vis[i]){ dfs(i,-1); int mk=0; if (d[i][0]<d[i][1]) mk = 0; else mk = 1; if (d[i][0] == d[i][1]) mk = f[i][0] > f[i][1] ? 0 : 1 ; sum += d[i][mk]; mx += f[i][mk]; } //print(); //cout << mk << endl; //mn = min(d[0][0],d[0][1]); printf("%d %d %d\n",sum,mx,m-mx); } int main() { int t; //freopen("G:\\Code\\1.txt","r",stdin); scanf("%d",&t); while(t--){ init(); solve(); } return 0; }
uva 10859 Placing Lampposts,树形dp
标签:uva 10859 placing lampposts 树形dp
原文地址:http://blog.csdn.net/timelimite/article/details/46063273