【ctsc2010 星際旅行】



   題意很簡單:

   給定一棵樹,問從根分別走到每個節點的最長路程,其中每個點給定lim,即最多從該點出發lim次,保證lim大於等於該點的度數。


   特別“鳴謝”ldl在他的模擬題中出了這道題。

   當題解講這要用樹形dp解網絡流模型時,都被驚異了,完全沒有想到網絡流,也完全沒有必要網絡流,atm在考場上直接有樹形dp AC之,考後hyc也自己YY出了另一種dp方法,

網絡流對於這道題真心不知道有什麼意義。

   std,atm 和 hyc的dp都有一個無語的問題,那就是細節比較多,轉移或統計時要使勁的推啊推,修改啊修改,各種地方的加減使得出錯概率很高,對於我這種傻×肯定寫起來比較吃力//用atm的方法寫了一半,被打斷,後來去寫就又推不出了。

 

   於是只要YY 啊  YY ,YY出一個幾乎沒有煩人的細節,甚至沒有寫dp過程的方法:

    

   正向思維難度很大,發現可以設計一個回退操作,而回退操作對於答案的影響僅爲1!
   那麼可以先用簡單的統計求出從根回到根得到的最大步數,然後用dfs序求解,dfs遞歸時,等於是要撤銷一步操作,分三種情況討論,只有加1和減1操作,完全沒有麻煩的。

    

   方法簡單到1A, 在衡八上刷到了rank 1(貌似是頭一次)

   http://www.zybbs.org/JudgeOnline/problemstatus.php?id=1917



# include <cstdlib>
# include <cmath>
# include <cstdio>
# include <cstring>

using namespace std;

const int V = 50000+10, E = 100000+10;
int top, linke[E], point[E], next[E];
int n, bj[V], d[V], cs[V], ans[V], now;  

void link(int x, int y) {++top; next[top]=linke[x];linke[x]=top;point[top]= y;}
int min(int x, int y) {return x<y?x:y;};

void dfs(int u, int fa)
{
	int up, ke;
	for (ke = linke[u]; ke; ke = next[ke])
	if (point[ke]!= fa)
	{
		dfs(point[ke], u);
		up = min(d[u], d[point[ke]]);
		d[u] -= up; d[point[ke]] -= up; now += 2*up;
		if (d[point[ke]]) cs[u] = point[ke];
	}
}
void dfs_ans(int u, int fa)
{
	int ke; ans[u] = now;
	for (ke = linke[u]; ke; ke = next[ke])
	if (point[ke]!= fa)
	{
		if (d[u] != 0) d[u]--, now++, bj[u] = 1;
	    else if (cs[point[ke]]!= 0) d[cs[point[ke]]]--, now++, bj[u] = 2;
		else d[point[ke]]++, now--, bj[u] = 3;
		dfs_ans(point[ke], u);
		if (bj[u] == 1) d[u]++, now--;
		else if (bj[u] == 2)  d[cs[point[ke]]]++, now--;
		else d[point[ke]]--, now++;
	}
}
int main()
{
	int i, x, y;
	freopen("child.in", "r", stdin);
	freopen("child.out", "w", stdout);
	scanf("%d", &n);
	for (i = 1; i <= n; i++) scanf("%d", &d[i]); 
	for (i = 1; i < n; i++) scanf("%d%d", &x, &y), ++x, ++y, link(x, y), link(y, x), d[x]--, d[y]--, now += 2;
	dfs(1, 0); 
	dfs_ans(1, 0);
	for (i = 1; i <= n; i++) printf("%d\n", ans[i]);
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章