题目链接————
题意大致是给你一棵树,然后每个节点都有一个计算器,有m个操作,每次在x节点处增加val的值,x相应的子树上的节点计算器都会增加val的值。
思路:
昨天晚上没想出好的做法,然后进行了m次dfs,当然理所当然的TLE。今天看discuss有人说先用数组记录,再用一次dfs进行前缀统计,我有点恍然大悟,然后就试了下,结果Wa了三组数据,我对一次dfs的做法有些质疑,如果两个点有公共子节点的话那怎么办呢?我想我蠢了,前提已经说了,这是棵树。。
若无向连通图G中有n个结点,n-1条边,则G为树 这是树的等价定义之一
后来看到有人给的数据,发现数据是随机给的。。。不是按照树的结构来的。
然后需要把节点之间设置为无向边,vis标记节点,dfs 或者bfs都可以。
BFS Code:
#include
using namespace std;
typedef long long LL;
const LL N = 200010;
struct Edge
{
LL next;
LL dis;
LL to;
}edge[N*2];
LL head[N*2];
LL res[N*2];
LL r[N*2];
LL tot;
LL n,m;
bool vis[N*2];
inline void add(LL from,LL to)
{
edge[++tot].next = head[from];
edge[tot].to = to;
head[from] = tot;
}
void init()
{
memset(head,-1,sizeof(head));
}
void bfs()
{
queue Q;
Q.push(1);
while(Q.size())
{
LL x = Q.front();
vis[x] = 1;
Q.pop();
for(LL i = head[x];~i;i = edge[i].next)
{
LL y = edge[i].to;
if(!vis[y]) {
res[y] += res[x];
Q.push(y);
}
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
init();
scanf("%lld%lld",&n,&m);
LL f,t;
for(LL i = 1;i<=n-1;++i)
{
scanf("%lld%lld",&f,&t);
add(f,t);
add(t,f);
}
for(LL i = 1;i<=m;++i)
{
scanf("%lld%lld",&f,&t);
res[f] += t;
}
bfs();
for(LL i = 1;i<=n;++i)
printf("%lld ",res[i]);
}
DFS Code:
#include
using namespace std;
typedef long long LL;
const int N = 200010;
struct Edge
{
int next;
int dis;
int to;
}edge[N*2];
int head[N*2];
int res[N*2];
int r[N*2];
int tot;
int n,m;
bool vis[N*2];
inline void add(int from,int to)
{
edge[++tot].next = head[from];
edge[tot].to = to;
head[from] = tot;
}
void init()
{
memset(head,-1,sizeof(head));
}
void dfs(int id)
{
vis[id] = 1;
for(int i = head[id];~i;i = edge[i].next)
{
int y = edge[i].to;
if(!vis[y]) res[y] += res[id],dfs(y);
}
}
int main()
{
//freopen("input.txt","r",stdin);
init();
scanf("%d%d",&n,&m);
int f,t;
for(int i = 1;i<=n-1;++i)
{
scanf("%d%d",&f,&t);
add(f,t);
add(t,f);
}
for(int i = 1;i<=m;++i)
{
scanf("%d%d",&f,&t);
res[f] += t;
}
dfs(1);
for(int i = 1;i<=n;++i)
printf("%d ",res[i]);
}
#include
using namespace std;
#define read(x) scanf("%d",&x)
#define write(x) printf("%d ",x)
const int N = 2e5;
int head[N+5],tot;
int d[N+5];
struct Edge
{
int next;
int to;
}edge[N*2+5];
inline void add(int from,int to)
{
edge[++tot].next = head[from];
edge[tot].to= to;
head[from] = tot;
}
void dfs(int x,int fa){
d[x] += d[fa];
for(int i = head[x];~i;i = edge[i].next)
{
int y = edge[i].to;
if(y!=fa) dfs(y,x);
}
}
int main()
{
memset(head,-1,sizeof(head));
int n,m;
read(n);read(m);
int f,t;
for(int i = 1;i<=n - 1;++i){
read(f);
read(t);
add(f,t);
add(t,f);
}
for(int i = 1;i<=m;++i){
read(f);
read(t);
d[f] += t;
}
dfs(1,0);
for(int i = 1;i<=n;++i) write(d[i]);
}