樹形dp
套路題,但是轉移有點麻煩。乙個很顯然的想法就是 先df
s 一次把子樹搞完,然後再df
s 加上其父節點對當前節點的影響。寫的略辣眼睛,除錯了好久。。dp
[0][
u],d
p[1]
[u] 分別表示以u為根,走回來和不走回來的最大值,第一次df
s 很簡單,普通的套路,第二次的時候,我們先把父親節點對於即將訪問的兒子節點的影響排除掉,再df
s ,然後回溯的時候還原即可,注意dp
[1][
u]的時候要記錄下次大,轉移的時候,若即將訪問的兒子節點
v 在
u往下走不回來的路上,就用次大值來減去影響。
//
// created by running photon
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define all(x) x.begin(), x.end()
#define ins(x) inserter(x, x,begin())
#define ll long long
#define clr(x) memset(x, 0, sizeof x)
using
namespace
std;
const
int inf = 0x3f3f3f3f;
const
int mod = 1e9 + 7;
const
int maxn = 2e5 + 10;
const
int maxv = 1e5 + 10;
const
double eps = 1e-9;
int pnt[maxn], nxt[maxn], val[maxv], head[maxv], cost[maxn], cnt;
void add_edge(int u, int v, int value)
int dp[2][maxv];
void dfs1(int u, int fa)
}for(int i = head[u]; ~i; i = nxt[i])
}}void dfs2(int u, int fa, int cost)
tmp = dp[1][u] = dp[0][u];
for(int i = head[u]; ~i; i = nxt[i])
else
if(dp[0][u] - max(0, dp[0][v] - cost[i] * 2) + (dp[1][v] - cost[i]) >= tmp)
}// printf("dp[0][%d] = %d dp[1][%d] = %d tmp = %d\n", u, dp[0][u], u, dp[1][u], tmp);
int l = dp[0][u], r = dp[1][u];
for(int i = head[u]; ~i; i = nxt[i])
if(dir == v) else
if(dp[0][v] - cost[i] * 2 > 0)
// printf("dir = %d\n", dir);
// printf("nxt%d = %d\n", v, dp[1][u]);
dfs2(v, u, cost[i]);
dp[0][u] = l, dp[1][u] = r;
}}int main()
dfs1(1, -1);
dfs2(1, -1, 0);
for(int i = 1; i <= n; i++)
}return
0;}
hdu3790解題報告
這裡起點和終點都是確定的,唯一有點小麻煩 也算不上什麼麻煩 就是這裡的權值有兩個,錢和路長,題目要求選擇最短路,對於一樣長度的路選擇錢最少的路.那麼我們每次就對路長鬆弛,對於路長一樣的在對錢鬆弛.不懂鬆弛操作的很抱歉 ac 840k 109ms include includeusing namesp...
hdu2647解題報告
題意 有個工廠的老闆給工人發獎金,每人基礎都是888,工人們有自己的想法,如 a 工人想要比 b 工人的獎金高,老闆想要使花的錢最少 那麼就可以 給b 888,給a 889 但是如果在此基礎上,b也想比a高,那麼就不能讓他們滿意,輸出 1 分析,根據題意可以得出乙個拓撲的關係,比如 一組資料 4 4...
hdu1080解題報告
後考研刷題時代正式開始,之前練dp意猶未盡,所以先拿dp題開刀,而且找了一道跟我原專業相關的題,基因序列匹配 當年學生物資訊學在書上看到了dna序列匹配的動態規劃演算法,現在終於實現了它 其實就是最長公共子串行lcs的變形題,ac 如下 include include define inf 9999...