Apple Tree树状数组、前向星、DFS序(C语言)

Apple Tree树状数组、前向星、DFS序(C语言)

题目

输入值

第一行包含一个整数Ñ(Ñ ≤100,000),这是树中的叉的数量。
接下来的N -1行分别包含两个整数u和v,这意味着fork u和fork v通过分支连接。
下一行包含的整数中号(中号≤100,000)。
以下中号行,每行包含一个消息,该消息或者是
“ Ç X ”,这意味着苹果上叉存在X已经变了。例如,如果叉子上有一个苹果,则卡卡(Kaka)摘下;否则,空叉上会长出一个新苹果。

“ Q x ”,表示查询叉子x上方子树中的苹果数量,包括叉子x上的苹果(如果存在),
请注意,树的开头充满了苹果

输出量

对于每个查询,每行输出相应的答案。
样本输入

3
1 2
1 3
3
Q 1
C 2
Q 1
样本输出

3
2

代码

#include <stdio.h>

typedef struct edge{
	int to;
	int next;
}Edge;

int n,c[100001],head[100001],in[100001],out[100001],ifexist[100001],count = 0;
Edge edge[100001];

int lowbit(int index){
	return index&(-index);
}


void addEdge(int father, int son){
	edge[++count].to = son;
	edge[count].next = head[father];
	head[father] = count;
}

int sum(int index){
	int res = 0;
	while(index>0){
		res += c[index];
		index -= lowbit(index);
	}
	return res;
}

void dfs(int index){
	in[index] = ++count;

	for(int i = head[index];i;i=edge[i].next){
		dfs(edge[i].to);
	} 
	out[index] = count;
}

void update(int index, int add){
	while(index <= n){
		c[index] += add;
		index += lowbit(index);
	}
}


int main(){
	int m,pre,son,result[10000],cnt = 0,i;
	char ch;
	scanf("%d",&n);
	for(i = 1; i<=n-1; i++){
		scanf("%d %d",&pre,&son);
		addEdge(pre,son);
	}
	count = 0;
	dfs(1);
	for(i = 1; i<=n; i++){
		update(in[i],1);
		ifexist[i] = 1;
	}
	scanf("%d",&m);
	
	for(i = 1; i<=m; i++){
		getchar();
		scanf("%c %d",&ch,&pre);
		if(ch == 'C'){
			if(ifexist[pre]){
				update(in[pre],-1);
			}
			else{
				update(in[pre],1);
			}
			ifexist[pre] = 1-ifexist[pre];
		}
		else if(ch == 'Q'){
			result[cnt++] = sum(out[pre]) - sum(in[pre] - 1);
		}
	}
	for(i = 0; i<cnt; i++){
		printf("%d\n",result[i]);
	}
	return 0;
} 
链式前向星(Dijkstra's Algorithm with Adjacency List)是一种图算法,用于寻找有向图或无向图中的最短路径。下面是使用C++实现的一个简单版本: ```cpp #include <iostream> #include <vector> #include <queue> #include <limits> using namespace std; struct Edge { int destination; int weight; }; class Graph { private: vector<vector<Edge>> adjList; // 使用邻接列表表示图 public: void addEdge(int src, int dest, int weight) { adjList[src].push_back({dest, weight}); } pair<int, int> dijkstra(int start) { priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // 小顶堆 vector<int> distance(start, numeric_limits<int>::max()); distance[start] = 0; pq.push({distance[start], start}); while (!pq.empty()) { int u = pq.top().second; pq.pop(); for (const auto &edge : adjList[u]) { int v = edge.destination; int newWeight = distance[u] + edge.weight; if (newWeight < distance[v]) { distance[v] = newWeight; pq.push({distance[v], v}); } } } return {distance[start], start}; } }; int main() { Graph g; // 添加边到图... pair<int, int> result = g.dijkstra(0); // 从节点0开始搜索最短路径 cout << "Shortest path from node 0 is to node " << result.second << " with a distance of " << result.first << endl; return 0; } ``` 在这个代码中,`Graph`类有一个邻接列表`adjList`来存储图的信息,`dijkstra`函数采用小顶堆实现优先队列,通过广度优先搜索找到起点到其他所有节点的最短距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒙奇·D·路飞·宝亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值