[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 ≤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.
 
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:\n",iCase++);

        for(int i=1;i<=n;i++)

        {

            if(i>1) putchar(' ');

            out(col[p[i]][0]);

        }

        printf("\n");

        if(n>1) out(col[p[convert(1)]][1]);

        for(int i=2;i<n;i++)

        {

            putchar(' ');

            out(col[p[convert(i)]][1]);

        }

        printf("\n");

    }

    return 0;

}

 

你可能感兴趣的:(tree)