Sep
12
SGU 143 解题手记
2007 解题报告 Popularity: unranked
给出的是一棵树,要求这棵树的权值最大的连通子图的权值。
树型DP可以:f(T)=sum{f(t)|f(t)>0,t是T的子树}。
存图用邻接表。
这样DP的话,树根肯定要被选入连通子图,所以还要枚举树根。复杂度是
,承受不了。
可以边DP边更新权值最大的连通子图的权值。
Submit 1: MLE on 8。去掉调试用的成员id。
Submit 2: MLE on 8。调整一下结构吧,不用程序员式的写法了,换个ws的。
Submit 3: MLE on 8。乱改一下。
Submit 4: TLE on 8。不仅TLE,而且MLE。看cpp标程,改用vector。
Submit 5: TLE on 8。这次没有MLE了。不用vector<vector>了,就用vector类型的数组。
Submit 6: AC。
感觉SGU上用list有问题,好像已经是第2次list过不去了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include <cstdio> #include <vector> using namespace std; struct treenode { int profit; bool visited; treenode():visited(false){}; }; int maxprofit=-16000000; vector<int> map[16000]; treenode town[16000]; void count(int T) { town[T].visited=true; for (vector<int>::iterator i=map[T].begin();i!=map[T].end();i++) if (!town[*i].visited) { count(*i); if (town[*i].profit>0) town[T].profit+=town[*i].profit; } maxprofit=max(town[T].profit,maxprofit); } int main() { int n; scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",&town[i-1].profit); for (int i=1;i<n;i++) { int a,b; scanf("%d %d",&a,&b); a--; b--; map[a].push_back(b); map[b].push_back(a); } count(0); printf("%d\n",maxprofit); return 0; } |
- http://www.briefdream.com/sgu-143/
- Tags:DP, SGU, 数组, 树型DP, 连通子图
- (0)comments | leave a reply
- Trackback URI