Tree
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2038 Accepted Submission(s): 391
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 ≤105),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, -105 ≤ k ≤ 105)
The first line of each case contains two integers N ,M (1 ≤ N, M ≤105),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, -105 ≤ k ≤ 105)
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
不行、好像有点晕、= = 见代码
#include <iostream> #include <algorithm> #include <cstdio> #include <queue> #include <cmath> #include <map> #include <iterator> #include <cstring> #include <string> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") //手动加栈、windows系统容易爆栈 #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define INF 0x7fffffff #define ll long long #define N 100002 struct Edge2 { int a,b; }s[N<<1]; struct Edge { int to,next; }edge[N<<1]; int head[N],tot; int size[N]; int deep[N]; int top[N]; int fa[N]; int son[N]; int p[N]; int fp[N]; int pos; int n,m; int col[N<<2][2]; //点权为0,边权为1 template <class T> inline bool input(T &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; } inline void out(int x) { if(x>9) out(x/10); putchar(x%10+'0'); } inline void init() { tot=0; pos=1; memset(col,0,sizeof(col)); memset(head,-1,sizeof(head)); memset(son,-1,sizeof(son)); } inline void addEdge(int x,int y) { edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot++; } inline void dfs1(int now,int pre,int d) { deep[now]=d; fa[now]=pre; size[now]=1; for(int i=head[now];i!=-1;i=edge[i].next) { int next=edge[i].to; if(next!=pre) { dfs1(next,now,d+1); size[now]+=size[next]; if(son[now]==-1 || size[next]>size[son[now]]) { son[now]=next; } } } } inline void dfs2(int now,int tp) { top[now]=tp; p[now]=pos++; fp[p[now]]=now; if(son[now]==-1) return; dfs2(son[now],tp); for(int i=head[now];i!=-1;i=edge[i].next) { int next=edge[i].to; if(next!=son[now] && next!=fa[now]) { dfs2(next,next); } } } inline void change_node(int x,int y,int z) { int f1=top[x]; int f2=top[y]; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(x,y); swap(f1,f2); } col[p[f1]][0]+=z; col[p[x]+1][0]-=z; x=fa[f1]; f1=top[x]; } if(deep[x]>deep[y]) swap(x,y); col[p[x]][0]+=z; col[p[y]+1][0]-=z; } inline void change_edge(int x,int y,int z) { int f1=top[x]; int f2=top[y]; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(x,y); swap(f1,f2); } col[p[f1]][1]+=z; col[p[x]+1][1]-=z; x=fa[f1]; f1=top[x]; } if(x==y) return; if(deep[x]>deep[y]) swap(x,y); col[p[x]+1][1]+=z; col[p[y]+1][1]-=z; } inline int convert(int pos) { int a=s[pos].a; int b=s[pos].b; if(deep[a]>deep[b]) return a; return b; } int main() { int T,iCase=1; input(T); while(T--) { init(); input(n); input(m); for(int i=1;i<n;i++) { input(s[i].a); input(s[i].b); addEdge(s[i].a,s[i].b); addEdge(s[i].b,s[i].a); } dfs1(1,0,0); dfs2(1,1); while(m--) { char op[10]; int a,b,c; scanf("%s",op); input(a);input(b);input(c); if(op[3]=='1') change_node(a,b,c); else change_edge(a,b,c); } for(int i=1;i<=n;i++) { col[i][0]+=col[i-1][0]; col[i][1]+=col[i-1][1]; } printf("Case #%d: ",iCase++); for(int i=1;i<=n;i++) { if(i>1) putchar(' '); out(col[p[i]][0]); } printf(" "); if(n>1) out(col[p[convert(1)]][1]); for(int i=2;i<n;i++) { putchar(' '); out(col[p[convert(i)]][1]); } printf(" "); } return 0; }