HDU 5044——Tree
来源:互联网 发布:宿舍楼网络规划 编辑:程序博客网 时间:2024/06/05 18:45
题意:两种操作,在点上面加权值或在边上面加权值,m次操作以后为每条边和每个点分别权值多少。
思路:LCA。这道题不知道为什么,提交的时候一直超时,然后上网找了kuangbin的标程也超时了。。。只有这个博客里的代码能过。http://blog.csdn.net/zz_1215/article/details/39649687
代码看了北大写的,然后自己写了一篇,到现在还没过。。
#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>#include<map>#include<set>#include<list>#include<stack>#include<algorithm>#include<queue>#include<vector>#include<time.h>#include<iomanip>#include<assert.h>using namespace std;const int maxn = 100005;struct Edge{ int u,v; int next; int id;}edge[maxn*2];int tot ;int first[maxn];void add(int uu,int vv,int id){ edge[tot].u = uu; edge[tot].v = vv; edge[tot].id = id; edge[tot].next = first[uu]; first[uu] = tot++;}int n,m;int dep[maxn];int pre[maxn];int dp[17][maxn];int q[maxn],qh,qt;int recE[maxn];int recN[maxn];void bfs(int u) { qh = qt = 0; q[qt ++] = u; for (int j = 0; j < 17; ++ j) dp[j][0] = -1; dep[u] = 0; pre[u] = -1; while (qh != qt) { u = q[qh ++]; for (int now = first[u], v; now != -1; now = edge[now].next) if (dp[0][u] != (v = edge[now].v)) { dp[0][v] = u; for (int j = 1; j < 17; ++ j) { if (dp[j - 1][v] == -1) { dp[j][v] = -1; } else { dp[j][v] = dp[j - 1][dp[j - 1][v]]; } } q[qt ++] = v; dep[v] = dep[u] + 1; pre[v] = edge[now].id; } }}int lca(int u, int v) { if (dep[u] < dep[v]) swap(u, v); int del = dep[u] - dep[v]; for (int j = 16; j >= 0; -- j) if (del >> j & 1) u = dp[j][u]; for (int j = 16; j >= 0; -- j) if (dp[j][u] != dp[j][v]) { u = dp[j][u]; v = dp[j][v]; } if (u != v) u = dp[0][u]; return u;}inline bool scan_d(int &ret){ char c;int sgn; if(c = getchar(),c == EOF)return 0; while(c!='-' && (c<'0'||c>'9'))c = getchar(); sgn = (c == '-')?-1:1; ret = (c == '-')?0 :c-'0'; while(c = getchar(),c>='0'&&c<='9')ret = ret*10 + (c-'0'); ret *=sgn; return 1;}int col[maxn];void putint(int x){ if(x<0){putchar('-'); x *= -1;} if(x == 0){ putchar('0'); return; } char s[20]; int cur = 0; while(x!=0){ s[cur++] = '0' + x%10; x/=10; } for(int i = cur-1;i>=0;i--){ putchar(s[i]); }}void solve(){ for(int i = qt-1; i>=0;--i){ int u = q[i]; if(dp[0][u] != -1){ recE[dp[0][u]] += recE[u]; recN[dp[0][u]] += recN[u]; } } for(int i = 1;i<n;++i)col[pre[i]] = recE[i]; for(int i = 0; i < n; ++i){ if(i)printf(" ");// printf("%d",recN[i]); putint(recN[i]); } puts(""); for(int i = 0; i < n-1 ; ++i){ if(i)printf(" ");// printf("%d",col[i]); putint(col[i]); } puts("");}int main(){// freopen("data.txt","r",stdin); int T; scan_d(T); int kase = 0; while(T -- ){ printf("Case #%d:\n",++kase); tot = 0;memset(first,-1,sizeof(first)); scan_d(n);scan_d(m); for(int i = 0; i < n-1;++i){ int u,v; scan_d(u);scan_d(v); u--;v--; add(u,v,i); add(v,u,i); } dep[0] = 0; pre[0] = -1; bfs(0); memset(recE,0,sizeof(recE)); memset(recN,0,sizeof(recN)); for(int i = 0; i < m; ++i){ int cmd; int u,v,k; scan_d(cmd); scan_d(u);scan_d(v);scan_d(k); u--;v--; int p = lca(u,v); if(cmd == 1){ recN[u] += k; recN[v] += k; recN[p] -= k; if(dp[0][p] != -1)recN[dp[0][p]] -= k; } else { recE[u] += k; recE[v] += k; recE[p] -= k*2; } } solve(); } return 0;}
0 0
- HDU 5044——Tree
- HDU 5044 Tree 树链剖分
- HDU 5044 Tree 树链剖分
- 【HDU】5044 Tree 树链剖分
- HDU 5044 Tree
- hdu 5044 Tree 树链剖分
- hdu 5044 Tree(树链剖分)
- HDU 5044 Tree --树链剖分
- hdu 5044 Tree
- hdu 5044 Tree 树链剖分
- HDU 5044 Tree
- HDU 5044Tree 树链剖分
- HDU-5044 Tree 树链剖分
- HDU 5044 - Tree (树链剖分)
- hdu 3094——A tree game
- HDU 5044 - Tree (树链剖分)
- HDU 5044 Tree(树链剖分)
- HDU 5044 Tree(LCA)
- 模拟器创建
- 1073. Scientific Notation (20) -- string,数字处理
- C - 这道题很难
- hdu 1599
- iOS开发学习之UIWindow
- HDU 5044——Tree
- UUID的组成
- WebApp开发技巧(手机网站开发注意事项)
- 写文章与写程序
- leetcode 142: Linked List Cycle II
- OutMan——Foundation框架中的NSString类和NSMutableString类
- 安卓UI布局常见警告
- Linux MTD驱动下的Nand Flash驱动中 mtd->write_oob和ecc.write_oob
- Linux编程——GCC的使用