• 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:
    ",++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 ;
    }
    

      

  • 相关阅读:
    DB2 字段操作
    解析二维码
    Eclipse tomcat 内存溢出
    hereim_美句_1
    js自定义函数默认参数的写法
    PHP和JS判断访问客户端的是PC还是移动设备
    lampp服务器配置httpd-vhosts.conf文件,设置多域名
    价值7000万的商业模式,羊毛出在狗身上,猪来买单
    确保 PHP 应用程序的安全
    美国淘金的故事
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/3999150.html
Copyright © 2020-2023  润新知