Tree
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 533 Accepted Submission(s): 106
Problem Description
You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are numbered from 1 to N
There are N - 1 edges numbered from 1 to N - 1.
Each node has a value and each edge has a value. The initial value is 0.
There are two kind of operation as follows:
● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
After finished M operation on the tree, please output the value of each node and edge.
There are N - 1 edges numbered from 1 to N - 1.
Each node has a value and each edge has a value. The initial value is 0.
There are two kind of operation as follows:
● ADD1 u v k: for nodes on the path from u to v, the value of these nodes increase by k.
● ADD2 u v k: for edges on the path from u to v, the value of these edges increase by k.
After finished M operation on the tree, please output the value of each node and edge.
Input
The first line of the input is T (1 ≤ T ≤ 20), which stands for the number of test cases you need to solve.
The first line of each case contains two integers N ,M (1 ≤ N, M ≤10 5),denoting the number of nodes and operations, respectively.
The next N - 1 lines, each lines contains two integers u, v(1 ≤ u, v ≤ N ), denote there is an edge between u,v and its initial value is 0.
For the next M line, contain instructions “ADD1 u v k” or “ADD2 u v k”. (1 ≤ u, v ≤ N, -10 5 ≤ k ≤ 10 5)
The first line of each case contains two integers N ,M (1 ≤ N, M ≤10 5),denoting the number of nodes and operations, respectively.
The next N - 1 lines, each lines contains two integers u, v(1 ≤ u, v ≤ N ), denote there is an edge between u,v and its initial value is 0.
For the next M line, contain instructions “ADD1 u v k” or “ADD2 u v k”. (1 ≤ u, v ≤ N, -10 5 ≤ k ≤ 10 5)
Output
For each test case, print a line “Case #t:”(without quotes, t means the index of the test case) at the beginning.
The second line contains N integer which means the value of each node.
The third line contains N - 1 integer which means the value of each edge according to the input order.
The second line contains N integer which means the value of each node.
The third line contains N - 1 integer which means the value of each edge according to the input order.
Sample Input
2 4 2 1 2 2 3 2 4 ADD1 1 4 1 ADD2 3 4 2 4 2 1 2 2 3 1 4 ADD1 1 4 5 ADD2 3 2 4
Sample Output
Case #1: 1 1 0 1 0 2 2 Case #2: 5 0 0 5 0 4 0
Source
Recommend
比赛时候问了句:卡时限真的好吗?
回答:卡的是姿势~
看来姿势真的很重要啊,学习了。。。。。
不说了,无力吐槽。
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#define maxn 100010
#define INF 0x7ffffff
#define efor(u) for(int i=head[u];i!=-1;i=e[i].next)
#define ll long long
using namespace std;
map<pair<int,int> ,int> q;
map<pair<int,int> ,int>::iterator it;
struct edge{int v,next;}e[2*maxn];
int head[maxn],tol;
int size[maxn],pre[maxn],son[maxn],dep[maxn],top[maxn],w[maxn],tw[maxn];
ll ans[maxn];
pair<int,int> p[maxn];
int n,m,va[maxn],tn;
template<class T> inline void readint(T& x) {
char c;
int mul = 1;
while((c = getchar()) != EOF){
if(c == '-')mul = -1;
if(c >= '0' && c <= '9'){
x = c-'0';
break;
}
}
if(c == EOF){x = EOF;return;}
while(c = getchar()){
if(c >= '0' && c <= '9'){
x = (x<<1)+(x<<3)+(c-'0');
}else break;
}
x *= mul;
}
void init(){
q.clear();
tol=0;
memset(head,-1,sizeof head);
}
void addedge(int u,int v){
e[tol].v=v,e[tol].next=head[u],head[u]=tol++;
}
void tree_init(){
tn=0,dep[1]=0;
}
void dfs(int u,int fa){
size[u]=1,son[u]=0,pre[u]=fa;
efor(u){
int v=e[i].v;
if(v!=fa){
dep[v]=dep[u]+1;
dfs(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
}
void build_tree(int x,int f){
q[make_pair(min(x,pre[x]),max(x,pre[x]))]=tn;
//cout<<x<<" "<<pre[x]<<"=>"<<tn<<endl;
w[x]=++tn,tw[tn]=x,top[x]=f;
if(son[x]>0) build_tree(son[x],f);
efor(x){
int v=e[i].v;
if(v!=pre[x]&&v!=son[x]) build_tree(v,v);
}
}
ll A[maxn],B[maxn];
void read(){
readint(n),readint(m);
for(int i=1;i<n;i++){
readint(p[i].first),readint(p[i].second);
addedge(p[i].first,p[i].second),addedge(p[i].second,p[i].first);
if(p[i].first>p[i].second) swap(p[i].first,p[i].second);
}
}
void gao(int x,int y,int z,int t){
if(t){
while(top[x]!=top[y]&&x!=y){
if(dep[top[x]]>dep[top[y]]) swap(x,y);
//cout<<w[top[y]]-1<<" "<<w[y]-1<<" "<<z<<endl;
B[w[top[y]]-1]+=z;
B[w[y]]-=z;
y=pre[top[y]];
}
if(x==y) return;
if(dep[x]<dep[y]){
//cout<<w[x]<<" "<<w[y]-1<<" "<<z<<endl,
B[w[x]]+=z;
B[w[y]]-=z;
}else{ //cout<<w[y]<<" "<<w[x]-1<<" "<<z<<endl,
B[w[y]]+=z;
B[w[x]]-=z;
}
}else{
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
//cout<<w[top[x]]<<" "<<w[x]+1<<endl;
A[w[top[x]]]+=z;
A[w[x]+1]-=z;
x=pre[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
//cout<<w[y]<<" "<<w[x]+1<<endl;
A[w[y]]+=z;
A[w[x]+1]-=z;
}
}
void solve(int ca){
printf("Case #%d:\n",ca);
tree_init();
dfs(1,1);
build_tree(1,1);
memset(A,0,sizeof A);
memset(B,0,sizeof B) ;
char s[10];
int x,y,z;
for(int i=0;i<m;i++){
scanf("%s",s);
readint(x),readint(y),readint(z);
if(x>y) swap(x,y);
if(s[3]=='1'){
gao(x,y,z,0);
}else{
gao(x,y,z,1);
}
}
for(int i=1;i<=n;i++){
A[i]+=A[i-1];
ans[tw[i]]=A[i];
}
for(int i=1;i<=n;i++){
if(i>1) printf(" ");
printf("%I64d",ans[i]);
}
printf("\n");
for(int i=1;i<n;i++){
B[i]+=B[i-1];
}
for(int i=1;i<n;i++){
ans[i]=B[q[p[i]]];
}
for(int i=1;i<n;i++){
if(i>1) printf(" ");
printf("%I64d",ans[i]);
}
printf("\n");
}
int T;
int main(){
scanf("%d",&T);
for(int ca=1;ca<=T;ca++){
init();
read();
solve(ca);
}
return 0;
}