夏令营讲课内容整理 Day 3.
- 树的性质
- 树的遍历
- 树的LCA
- 树上前缀和
- 每个点的父亲是谁
- 每个点的深度
- 每个点距离根节点的距离
- 其他的附加信息(例如:子树和,子树最大值。。)
void dfs(int now)
{
deep[now]=deep[fa[now]]+;
sum[now]=value[now]; maxx[now]=value[now];
for 遍历从now出发的每一条边,边到达的点是v
if (v != fa[now])
{
fa[v]=now;
dfs(v);
sum[now]+=sum[v]; maxx[now]=max(maxx[now], maxx[v]);
}
}
struct Edge_tree{
int u,v,w;
int next; };
Edge_tree edge[maxn];
int cnt = ;
int first[maxn];
void add_edge(int from,int to,int dis){
edge[++cnt].u = from;
edge[cnt].v = to;
edge[cnt].w = dis;
edge[cnt].next = fisrt[from];
first[from] =cnt; /*
作为一棵无向树,还需要反向进行加边操作。
图的邻接表不也是这样吗?
*/
edge[++cnt].v = from;
edge[cnt].u = to;
edge[cnt].w = dis;
edge[cnt].next = first[to];
first[to] = cnt;
/*
这超酷,是不是?
以前我还从来没有想过可以使用邻接表存一棵树!
这可以说是最新操作了。
*/
} void dfs_tree(int x,int fa){
//cout << x << " ";
for (int i = first[x];i!=;i = edge[i].next)
if (edge[i].v != fa)
dfs_tree(edge[i].v,x);
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 2333
using namespace std;
int f[maxn][maxn];
int father[maxn];
int deep[maxn];
vector<int> tree; void dfs(int x){
f[x][] = father[x];
for (int i=;i<=n;i++)
f[x][i] = f[f[x][i-]][i-];
for (int i=;i<tree[x].size();i++){
if (tree[x][i]!=father[x]){
int y = tree[x][i];
father[y] = x;
deep[y] = deep[x]+;
dfs(y);
}
}
}//从根节点开始dfs,预处理f数组 //查询LCA:
int lca(int x,int y){
if (deep[x]<deep[y])
swap(x,y);
for (int i=n;i>=;i--)
if (deep[y] <= deep[f[x][i]])
x = f[x][i];
if (x==y)
return x;
for (int i=n;i>=;i--)
if (f[x][i]!=f[y][i]){
x = f[x][i];
y = f[y][i];
}
return f[x][];
} int main(){
//do something
return ;
}
- 根路径前缀和
- 子树前缀和
- 邻接矩阵 && 邻接表
- 图的最短路径算法
- 最小生成树
- 拓扑排序(我之前好像总结过
struct Edge{
long long int from,to,dis;
};
Edge edge[maxn];
long long int head[maxn];
long long int cnt = ;
void add_edge(long long int from,long long int to,long long int dis){
edge[++cnt].from = head[from];
edge[cnt].to = to;
edge[cnt].dis = dis;
head[from] = cnt;
}
这是我最常用的邻接表。开一个struct存边。
加边操作其实就是往链表里塞一个节点罢了。那个head数组表示第i个点连接的下一条边的编号。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#define ll long long
#define INF 2147483647
using namespace std;
int n,m,s,head[],cnt;
ll dis[];
bool used[];
struct Edge{
int to,from,dis;
}edge[]; void add_edge(int u,int v,int dis){
edge[cnt].to=v;
edge[cnt].from=head[u];
edge[cnt].dis=dis;
head[u]=cnt++;
}
typedef pair<int,int> P;
void dijkstra(int s){
priority_queue<P,vector<P>,greater<P> > q;
fill(dis,dis+n+,INF);
fill(used,used+n+,false);
dis[s]=;
q.push(P(,s));
while(!q.empty()){
P p=q.top();q.pop();
int u=p.second;
if(used[u]) continue;
used[u]=true;
int pp=head[u];
while(pp!=-){
int v=edge[pp].to;
if(!used[v]&&dis[v]>dis[u]+edge[pp].dis){
dis[v]=dis[u]+edge[pp].dis;
q.push(P(dis[v],v));
}
pp=edge[pp].from;
}
}
}
int main(){
memset(head,-,sizeof(head));
cin>>n>>m>>s;
for(int i=;i<=m;i++){
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
add_edge(u,v,d);
}
dijkstra(s);
for(int i=;i<=n;i++) printf("%lld ",dis[i]);
return ;
}
用了一个pair,对组,用来存放最短路径
priority_queue<P,vector<P>,greater<P> > q;这样声明,便成了小根堆,我们每次都要取最小的边。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 5000015
#define INF 2147483647
#define ms(x) memset(x,0,sizeof(x));
using namespace std;
struct Edge{
long long int from,to,dis;
};
Edge edge[maxn];
long long int n,m,s,u,v,d;
long long int head[maxn];
long long int dis[maxn];
bool inq[maxn];
long long int cnt = ;
void add_edge(long long int from,long long int to,long long int dis){
edge[++cnt].from = head[from];
edge[cnt].to = to;
edge[cnt].dis = dis;
head[from] = cnt;
} void spfa(void){
queue<long long int> q;
q.push(s);
ms(inq);
inq[s] = true;
for (int i=;i<=n;i++)
dis[i] = INF;
dis[s] = ;
while (!q.empty()){
long long int u = q.front();
q.pop();
inq[s] = false;
for (int i=head[u];i!=;i=edge[i].from){
long long int v = edge[i].to;
long long int w = edge[i].dis;
if (dis[u]+w < dis[v]){
dis[v] = w+ dis[u];
if (!inq[v]){
q.push(v);
inq[v] = true;
}
}
}
} } int main(){
cin >> n >> m >> s;
for (int i=;i<=m;i++){
cin >> u >> v >> d;
add_edge(u,v,d);
}
spfa();
for (int i=;i<=n;i++)
cout << dis[i] << " ";
return ;
}
如果要判断负环的话,再加一个数组记录每个点入队的次数,如果在入队操作时发现一个点的入队次数超过n,则一定存在负环。
.初始化 father[x] = [x],tot =
.对所有边进行边权排序,设边数为m
.for (int i=;i<=m;i++){
if 当前的这条边连接的两个点不属于同一集合{
合并两集合,并把边(u,v)加入最小生成树
tot += w(u,v),k++
if (k==n-)
break;
}
}
夏令营讲课内容整理 Day 3.的更多相关文章
- 夏令营讲课内容整理 Day 7.
Day7是夏令营的最后一天,这一天主要讲了骗分技巧和往年经典的一些NOIP试题以及比赛策略. 这天有个小插曲,上午的day7T3是一道和树有关的题,我是想破脑袋也想不出来,正解写不出来就写暴力吧,暴力 ...
- 夏令营讲课内容整理Day 0.
今年没有发纸质讲义是最气的.还好我留了点课件. 第一次用这个估计也不怎么会用,但尝试一下新事物总是好的. 前四天gty哥哥讲的内容和去年差不多,后三天zhn大佬讲的内容有点难,努力去理解吧. 毕竟知识 ...
- 夏令营讲课内容整理 Day 6 Part 3.
第三部分主要讲的是倍增思想及其应用. 在Day3的整理中,我简要提到了倍增思想,我们来回顾一下. 倍增是根据已经得到的信息,将考虑的范围扩大一倍,从而加速操作的一种思想,它在变化规则相同的情况下,加速 ...
- 夏令营讲课内容整理 Day 6 Part 2.
Day 6的第二部分,数论 数论是纯粹数学的分支之一,主要研究整数的性质 1.一些符号: a mod b 代表a除以b得到的余数 a|b a是b的约数 floor(x) 代表x的下取整,即小于等于 ...
- 夏令营讲课内容整理 Day 6 Part 1.
Day6讲了三个大部分的内容. 1.STL 2.初等数论 3.倍增 Part1主要与STL有关. 1.概述 STL的英文全名叫Standard Template Library,翻译成中文就叫标准 ...
- 夏令营讲课内容整理 Day 5.
DP专场.. 动态规划是运筹学的一个分支, 求解决策过程最优化的数学方法. 我们一般把动态规划简称为DP(Dynamic Programming) 1.动态规划的背包问题 有一个容量为m的背包,有 ...
- 夏令营讲课内容整理 Day 4.
本日主要内容就是搜索(打暴力 搜索可以说是OIer必会的算法,同时也是OI系列赛事常考的算法之一. 有很多的题目都可以通过暴力搜索拿到部分分,而在暴力搜索的基础上再加一些剪枝优化, 就有可能会拿到更多 ...
- 夏令营讲课内容整理 Day 2.
本日主要内容是并查集和堆. 并查集 并查集是一种树型的数据结构,通常用来处理不同集合间的元素之间的合并与查找问题.一个并查集支持三个基本功能:合并.查找和判断.举一个通俗的例子,我和lhz认识,lhz ...
- 夏令营讲课内容整理Day 1.
主要内容是栈和队列. 1. 栈 运算受到限制的线性表.只允许从一端进行插入和删除等操作.这一端便是栈顶,另一端便是栈底. 其实可以把栈想象层任何有底无盖的柱状的容器...毕竟栈满足后进先出的特性.计 ...
随机推荐
- c语言中标识符的作用域
1.代码块作用域(block scope) 位于一对花括号之间的所有语句称为一个代码块,在代码块的开始位置声明的标识符具有代码块作用域,表示它们可以被这个代码中的所有语句访问.函数定义的形式参数在函数 ...
- FineReport调用存储过程
"总结一下本人在项目中遇到的问题,如何在数据库表名未知且作为一种查询条件的情况下查询出数据集,仅能通过FineReport+Oracle实现. 首先分析这个问题的条件和要求: 条件:只有一个 ...
- java 跳出多层循环
lableB: for(int i=0;i<10;i++){ lableA: for(int j=0;j<10;j++){ System.out.println(j); if(j==1){ ...
- Sqoop导入导出的几个例子
Sqoop导入导出的几个例子 http://sqoop.apache.org/docs/1.4.6/SqoopUserGuide.html#_importing_data_into_hive no ...
- redis常见使用场景下PHP实现
基于redis字符串string类型的简单缓存实现 <?php //简单字符串缓存 $redis = new \Redis(); $redis->connect('127.0.0.1',6 ...
- J.U.C JMM. pipeline.指令重排序,happen-before(续MESI协议)
缓存(Cache) CPU的读/写(以及取指令)单元正常情况下甚至都不能直接访问内存——这是物理结构决定的:CPU都没有管脚直接连到内存.相反,CPU和一级缓存(L1 Cache)通讯,而 ...
- 直接请求转发(Forward)和间接请求转发(Redirect)两种区别?
用户向服务器发送了一次HTTP请求,该请求肯能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用户是感觉不到请求转发的.根据转发方式的不同,可以区分为直接请求转发 ...
- 【fail2ban】使用fail2ban进行攻击防范
使用fail2ban进行攻击防范 转自:https://kyle.ai/blog/6215.html 最近总有一些无聊的人,会来扫描一下我的服务器,看有没有啥漏洞可以利用的... 可以看到类似这样的4 ...
- 前后端分离之CORS和WebApi
目前的项目是前端mv*+api的方式进行开发的,以前都是没有跨域的方案,前后端人员在同一个解决方案里边进行开发,前端人员要用IIS或VS来开发和调试Api,这样就很不方便,迫切需要跨域访问Api. 评 ...
- Linux指令--chgrp
在lunix系统里,文件或目录的权限的掌控以拥有者及所诉群组来管理.可以使用chgrp指令取变更文件与目录所属群组,这种方式采用群组名称或群组识别码都可以.Chgrp命令就是change group的 ...