http://www.lydsy.com/JudgeOnline/problem.php?id=1791
http://www.spoj.com/OI/problems/ISLAND/
D2T1 Islands
Brief description:
给定一个树加一条边。。求这个图的最长链。
Analysis:
一棵树加一条边就是会有一个环。。讨论最长链。。
不在环上。。那么规约到树上最长链。。
在环上。。
那么设 d[i] 表示环上某个点向下所能到达的最远点。
。。 s[i] 表示环上第 0 个结点,沿着正方向到第 i 个结点之间的距离。。。
。。dist(i, j) 表示环上两个点的最长路径。。讨论方向。。
。。有 dist(i, j) = max(s[i] – s[j], ss – (s[i] – s[j))
。。ss 表示整个环的长度。。
答案就是 max{ d[i] + d[j] + dist(i, j) | j < i } 把上式拆开。。 就是每次。。找。。 max{ d[i] + s[i] + max(d[j] - s[j]), ss + d[i]-s[i] +max(d[j] + s[j]); } 然后 O(n) 扫描就可以了。。。 [cpp] //}/* .................................................................................................................................. */ const int N = int(1e6) + 9, M = 2*N; LL dd[N], d[N], s[N]; int c[N]; int nn; int Q[N], cz, op, uu; int hd[N], prd[M], suc[M], to[M], ww[N]; int n; #define aa to[i^1] #define bb to[i] #define w ww[i/2] inline void del(int i){ if (hd[aa] == i) prd[hd[aa] = suc[i]] = 0; else suc[prd[suc[i]] = prd[i]] = suc[i]; } inline void dell(int i){ del(i), del(i^1); } int vis[N]; bool st[N]; #define v (bb) bool dfs(int u, int p = -1){ // Find_Circle vis[u] = 1; REP_G(i, u) if (i != p){ if (vis[v]) st[v] = 1; if (vis[v] || dfs(v, i^1)){ c[nn] = v, s[nn+1] = s[nn] + w, ++nn, dell(i); return !st[u]; } } return 0; } LL f(int x){ nn = 0, dfs(x); LL z = 0; REP(ii, nn){ int s = c[ii], ss = s; dd[ii] = 0; cz = 0, op = 1; Q[0] = s; d[s] = 0; vis[s] = 2; while (cz < op){ int u = Q[cz++]; REP_G(i, u) if (vis[v] != 2){ d[v] = d[u] + w; vis[v] = 2, Q[op++] = v; if (d[v] > dd[ii]){ dd[ii] = d[v]; ss = v; } } } cz = 0, op = 1; Q[0] = ss, d[ss] = 0; vis[ss] = 3; while (cz < op){ int u = Q[cz++]; REP_G(i, u) if (vis[v] != 3){ d[v] = d[u] + w; vis[v] = 3, Q[op++] = v; checkMax(z, d[v]); } } } #define d dd LL ss=s[nn],pre1=d[0]-s[0],pre2=d[0]+s[0]; FOR(i,1,nn){ checkMax(z, d[i]+max(s[i]+pre1,ss-s[i]+pre2)); checkMax(pre1, d[i]-s[i]), checkMax(pre2, d[i]+s[i]); } return z; } int main(){ #ifndef ONLINE_JUDGE freopen("isl19g.in", "r", stdin); freopen("isl5.txt", "w", stdout); #endif RD(n); for (int i=2,a=1;i<=n<<1;++a){ aa = a, RD(bb, w); prd[hd[aa]] = i, suc[i] = hd[aa], hd[aa] = i++; prd[hd[aa]] = i, suc[i] = hd[aa], hd[aa] = i++; } LL z = 0; REP_1(i, n) if (!vis[i]) z += f(i); OT(z); } [/cpp]




 Alca
 Alca Amber
 Amber Belleve Invis
 Belleve Invis Chensiting123
 Chensiting123 Edward_mj
 Edward_mj Fotile96
 Fotile96 Hlworld
 Hlworld Kuangbin
 Kuangbin Liyaos
 Liyaos Lwins
 Lwins LYPenny
 LYPenny Mato 完整版
 Mato 完整版 Mikeni2006
 Mikeni2006 Mzry
 Mzry Nagatsuki
 Nagatsuki Neko13
 Neko13 Oneplus
 Oneplus Rukata
 Rukata Seter
 Seter Sevenkplus
 Sevenkplus Sevenzero
 Sevenzero Shirleycrow
 Shirleycrow Vfleaking
 Vfleaking wangzhpp
 wangzhpp Watashi
 Watashi WJMZBMR
 WJMZBMR Wywcgs
 Wywcgs XadillaX
 XadillaX Yangzhe
 Yangzhe 三途川玉子
 三途川玉子 About.me
 About.me Vijos
 Vijos
