国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Spoj FTOUR Free Tour II

2019-11-08 02:59:20
字體:
來源:轉載
供稿:網友

傳送門

http://www.spoj.com/PRoblems/FTOUR2/en/


題目大意

給出一棵樹,其中每一節點都有一個顏色(黑色或白色),每條邊都有一個權值,現要求在樹中找出一條鏈,使得鏈上的黑點數不超過給定的數k ,求權值和最大


我的想法

國家集訓隊論文 : http://wenku.baidu.com/view/8861df38376baf1ffc4fada8.html 對鏈的操作可以想到用點分治。 如果一條鏈不包括當前(根)節點的話,就遞歸好了 如果包括根節點,那就把那條鏈從根節點劈開,剩下的兩段一定在不同的子樹中(如果這條鏈的一個端點就是根節點的話那就說另一段在某子樹中長度為0),這要也可以保證不會算出不合法的情況。 然后我就這么劈開,提交,TLE 因為在遞歸子樹的時候有講究,令d(i) 表示第i 棵子樹中的包含最多黑色節點的鏈的黑色節點數,如果d(i)>k ,令d(i)=k ,因為如果一條鏈包含了多于k 個黑色節點的話肯定不合法,然后先從小的d(i) 入手遞歸,在遞歸大的。 再提交,WA 因為我忽略了根節點是黑色的情況 繼續提交,WA 因為k?d(i)?black(u)d(i)=ku 是黑色節點的時候成了負數 越錯越勇,WA 因為在當兩顆子樹的黑點數加起來都小于k 的時候k?d(i)?black(u) 是沒有意義的,于是我把它改成min(d(j),k?d(i)?black(u)) 第5次提交,WA 很多變量沒有初始化,就比如說遞歸子樹的時候d[] 沒有清0,找重心的時候子樹大小是錯的.. 最后第8次才A


代碼

#include <cstdio>#include <cstring>#include <algorithm>#define x first#define y second#define REP(i,_begin,_end) for(int i=(_begin);i!=(_end);++i)template<class T>T min(const T &a,const T &b){return a < b ? a : b;}template<class T>T max(const T &a,const T &b){return a > b ? a : b;}template<class T>bool chkmin(T &a,const T &b){return a > b ? a=b, 1 : 0;}template<class T>bool chkmax(T &a,const T &b){return a < b ? a=b, 1 : 0;}const int SN = 200000 + 50;const int Inf = 0x3f3f3f3f;int head[SN], nxt[SN<<1], to[SN<<1], wei[SN<<1], tot;int black[SN], size[SN], f[SN], g[SN], ans, sum, cnt, rt, n, m, k;std :: pair<int,int> deep[SN];bool vis[SN];void Read(int &);void Add(int, int, int);void GetRt(int, int);void GetG(int, int, int, int);void GetDeep(int, int, int, int);void GetSize(int, int);void Doit(int);int main(){ int x, y, z; Read(n), Read(k), Read(m); REP(i, 0, m) Read(x), black[x]=1; REP(i, 1, n) Read(x), Read(y), Read(z), Add(x, y, z); sum=n, cnt=Inf, GetRt(1,-1), Doit(rt); printf("%d/n",ans); return 0;}void Read(int &in){ char ch;int f=1; for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1; for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0'; in *= f;}void Add(int u,int v,int w){ nxt[++tot]=head[u];head[u]=tot;to[tot]=v;wei[tot]=w; nxt[++tot]=head[v];head[v]=tot;to[tot]=u;wei[tot]=w;}void GetRt(int u,int fa){ int mx = 0; size[u] = 1; for(int i=head[u];i;i=nxt[i]) if(!vis[to[i]] && to[i]!=fa){ GetRt(to[i],u); size[u] += size[to[i]]; chkmax(mx,size[to[i]]); } if(chkmin(cnt,max(mx,sum-size[u]))) rt = u;}void GetG(int u,int fa,int t,int d){ if(t > k) return ; for(int i=head[u];i;i=nxt[i]) if(!vis[to[i]] && to[i]!=fa){ if(t+black[to[i]]<=k) chkmax(g[t+black[to[i]]],d+wei[i]); GetG(to[i], u, t+black[to[i]], d+wei[i]); }}void GetDeep(int u,int fa,int depth,int t){ if(depth > k) return; chkmax(deep[t].x, depth); for(int i=head[u];i;i=nxt[i]) if(!vis[to[i]] && to[i]!=fa) GetDeep(to[i],u,depth+black[to[i]],t);}void GetSize(int u,int fa){ size[u] = 1; for(int i=head[u];i;i=nxt[i]) if(!vis[to[i]] && to[i]!=fa) GetSize(to[i],u), size[u]+=size[to[i]];}void Doit(int u){ int t = 0; vis[u] = true; for(int i=head[u];i;i=nxt[i]) if(!vis[to[i]]) deep[t].x=0, GetDeep(to[i],u,black[to[i]],t), deep[t++].y=i; std :: sort(deep, deep+t); REP(i, 0, t) { chkmax(g[black[to[deep[i].y]]], wei[deep[i].y]); GetG(to[deep[i].y], u, black[to[deep[i].y]], wei[deep[i].y]); REP(j, 1, deep[i].x+1) chkmax(g[j], g[j-1]), chkmax(f[j], f[j-1]); REP(j, 0, deep[i].x+1) if(k-black[u]-j>=0) chkmax(ans, g[j]+f[min(deep[i].x,k-black[u]-j)]); REP(j, 0, deep[i].x+1) chkmax(f[j], g[j]), g[j] = 0; } REP(i, 0, deep[t-1].x+1) f[i] = 0; GetSize(u, -1); for(int i=head[u];i;i=nxt[i]) if(!vis[to[i]]) sum=size[to[i]], cnt=Inf, GetRt(to[i],u), Doit(rt);}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 卫辉市| 龙井市| 微博| 娄底市| 福贡县| 聂荣县| 黄山市| 金山区| 保靖县| 资阳市| 灵寿县| 吉安市| 鄂伦春自治旗| 百色市| 小金县| 青神县| 教育| 哈密市| 嘉峪关市| 马公市| 庐江县| 介休市| 察隅县| 冷水江市| 靖边县| 古丈县| 来宾市| 巧家县| 新绛县| 大石桥市| 虎林市| 郑州市| 蓝山县| 吴川市| 屏山县| 乌鲁木齐市| 峨边| 沁水县| 莲花县| 长垣县| 连城县|