zoukankan      html  css  js  c++  java
  • [HDU 5044] Tree

    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.
     
    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
     

    不行、好像有点晕、= = 见代码

    #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;
    }
    趁着还有梦想、将AC进行到底~~~by 452181625
  • 相关阅读:
    面向消息的持久通信与面向流的通信
    通信协议
    [1]序章,基本
    深拷贝和浅拷贝
    堆/栈 内存管理相关
    C++的四种cast(显示类型转换)
    智能指针相关
    C++对象模型:单继承,多继承,虚继承
    HTTP/TCP
    [读书笔记] 为什么绝不在构造/析构函数中调用virtual函数
  • 原文地址:https://www.cnblogs.com/hate13/p/4087481.html
Copyright © 2011-2022 走看看