hdu5044 Tree

Tree

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 845    Accepted Submission(s): 162


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.
 

 

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)
 

 

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.
 

 

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
 
思路:先求lca,对于点的修改,对于 u,v,假设 lca等于 u ,那么add[v] += val ;add[fa[u]] -= val ;
如果lca不为 u,v那么 ......看代码吧,
最后从根节点开始 up , add[fa] += add[son] ; 这个add[u],就是u 增加的值
对于边的修改,我们先转为有根树,然后把边的权值分给两个端点中,深度高的那个,然后
就可以和点修改差不多了,具体看代码吧
这题真吭,很和谐的树链分割过不了。。。。
#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<map>
#include<ctime>
#include<bitset>
#define LL long long
#define INF 999999
#define mod 20140518
#define maxn 100010
using namespace std;

int head[maxn],next1[maxn*2],to[maxn*2] ;
int top ,id[maxn] ,n ,num[maxn],dep[maxn];
int xx[maxn],yy[maxn],cc[maxn],e[maxn];
int fa[maxn];
LL ans[maxn],add1[maxn],add2[maxn];
int out[maxn];
bool vi[maxn] ;
struct node
{
    int v,id;
    node(){}
    node(int x,int y )
    {
        v = x ;id = y ;
    }
};
vector<node>qe[maxn];

void Unit(int u,int v )
{
    next1[top] = head[u] ;to[top] = v ;
    head[u] = top++;
}
int find(int x )
{
    if(x != fa[x])
        fa[x] = find(fa[x]) ;
    return fa[x];
}
void dfs(int u ,int f)
{
    fa[u]=u;
    vi[u] = true;
    for(int i = head[u] ; i != -1 ; i = next1[i])
    {
        int v = to[i] ;
        if(v==f) continue;
        dfs(v,u) ;
        fa[v] = u ;
    }
    node a;
    for(int i = 0 ; i < qe[u].size();i++)
    {
        a = qe[u][i] ;
        if(!vi[a.v]) continue ;
        num[a.id] = find(a.v) ;
    }
}
void bfs(int s)
{
    memset(vi,0,sizeof(vi)) ;
    memset(out,0,sizeof(out));
    queue<int>q ;
    q.push(s) ;
    dep[s]=0;
    vi[s] = true ;
    while(!q.empty())
    {
        int u = q.front() ;
        q.pop() ;
        for(int i = head[u] ; i != -1 ; i = next1[i])
        {
            int v = to[i] ;
            if(vi[v]) continue ;
            out[u]++;
            vi[v] = true ;
            dep[v]=u;
            id[v] = i/2+1 ;
            q.push(v) ;
        }
    }
}
int next_int() {
    char ch;
    int res;
    bool neg;
    while (ch = getchar(), !isdigit(ch) && ch != '-')
        ;
    if (ch == '-') {
        neg = true;
        res = 0;
    } else {
        neg = false;
        res = ch - '0';
    }
    while (ch = getchar(), isdigit(ch))
        res = res * 10 + ch - '0';
    return neg ? -res : res;
}
int main()
{
    char a[10] ;
    int m,x,y,i,j,u,v;
    int T,c ,case1=0;
    cin >> T ;
    while( T-- )
    {
        scanf("%d%d",&n,&m) ;
        for(i = 0 ; i <= n ;i++)qe[i].clear();
        memset(head,-1,sizeof(head)) ;
        top=0;
        for( i = 1 ; i < n ;i++)
        {
            x = next_int();
            y = next_int();
            Unit(x,y) ;
            Unit(y,x) ;
        }
        bfs(1) ;
        for( i = 1 ; i <= m ;i++)
        {
            scanf("%s",a) ;
            x = next_int();
            y = next_int();
            c = next_int();
            qe[x].push_back(node(y,i));
            qe[y].push_back(node(x,i));
            xx[i]=x;yy[i]=y;
            cc[i]=c;
            if(a[3]=='1')
            {
                e[i]=1;
            }
            else
            {
                e[i]=0;
            }
        }
        memset(vi,0,sizeof(vi)) ;
        memset(add1,0,sizeof(add1));
        memset(add2,0,sizeof(add2));
        dfs(1,-1);
        int f;
        for( i = 1 ; i <= m ;i++)
        {
            f = num[i];
            u=xx[i];
            v=yy[i];
            if(e[i])
            {
                if(u==v)
                {
                    add1[u] += cc[i];
                    add1[dep[f]] -= cc[i];
                }
                else{
                    add1[u] += cc[i];
                    add1[v] += cc[i];
                    add1[dep[f]] -= cc[i];
                    add1[f] -= cc[i];
                }
            }
            else{
                if(u==v)
                {
                    add2[u] += cc[i];
                    add2[f] -= cc[i];
                }
                else{
                    add2[u] += cc[i];
                    add2[v] += cc[i];
                    add2[f] -= 2*cc[i];
                }
            }
        }
        queue<int>q;
        for( i = 1 ; i <= n ;i++)if(!out[i])
        {
           q.push(i);
        }
        memset(vi,0,sizeof(vi));
        while(!q.empty())
        {
            u = q.front();q.pop();
            v = dep[u] ;
            if(v==0) continue ;
            add1[v] += add1[u] ;
            add2[v] += add2[u] ;
            out[v]--;
            if(out[v]==0)q.push(v);
        }
        printf("Case #%d:\n",++case1);
        bool flag=false;
        for( i = 1 ; i <= n ;i++)
        {
            if(flag)printf(" ") ;
            flag=true;
            printf("%I64d",add1[i]);
        }
        puts("");
        flag=false;
        for( i = 2 ; i <= n ;i++)
        {
            ans[id[i]] = add2[i];
        }
        for( i = 1 ; i <n ;i++)
        {
            if(flag) printf(" ") ;
            flag=true;
            printf("%I64d",ans[i]);
        }
        puts("");
    }
    return 0 ;
}

  

posted @ 2014-09-28 22:48  _log__  阅读(162)  评论(0编辑  收藏  举报