树/图的存储方式
1 邻接矩阵
bool/int map[MAXN][MAXN];
map[i][j]表示 i 到 j 是否连通 / 权值是多少
遍历
for()
for()
遍历整个数组
2 链式前向星
一种把节点 u 所连的边集合 {E} “串成一条 “链” ” 的表示方法
int head[MAXN]; // head[u] 表示 与 u 相连通的 “链” 的 “头”(链的起点)边的 编号;
struct Edge{
int to; // edge[i].to 表示 第i条有向边 到达的点 v(起始点为u,无向边存两遍就是了)
int next; // edge[i].next 表示 第i条有向边 所在链的 下一条 边的 编号 ;
int dis; //edge[i].dis 表示 第i条有向边 的 权值 ;
}edge[MAXN*2];//*2因为无向图要存两遍
遍历 与 u 相连的所有的 点 或 边
for(int i=head[u]; // i 初始化为 链头 边 的 编号
i; // i为 0 时表示遍历到了 这条链的 链尾
i=edge[i].next;) // i 不断“指向”(更新为) 链中的 下一条边的 编号
i 为 u 联通的边 的 编号,edge[i] 为权值,
edge[i].to 为 u 联通的点 的 编号;
3 vector (不知道叫啥名)
可以理解为 邻接矩阵的优化
vector<int>vec[MAXN] // 只存到达的节点
vector<pair<int,int> >vec[MAXN] // vec[u][i].first 为到达的节点编号, vec[u][i].second 为此边的权值;
插入 u 与 v 相连
vec[u].push_back(v),
vec[v].push_back(u);
若有权值 // make_pair(a,b) 可以 。。。额。 自己体会吧
vec[u].push_back(make_pair(v,dis)),
vec[v].push_back(make_pair(u,dis));
遍历
for(int i=vec[u][0];
i<vec[u].size();
i++;)
以 洛谷 P2420 让我们异或吧 为例题
用 vector 和 链式前向星 分别 存储
对比二者差别
这道题会不会的吧,其实只是对比效率罢了
vector 代码短 好写 可读性强
#include<bits/stdc++.h> using namespace std; #define N 100005 int tree[N],n,m; bool vis[N]; vector<pair<int,int> >vec[N]; void dfs(int k){ vis[k]=1; int v; for(int i=0;i<vec[k].size();i++){ v=vec[k][i].first; if(!vis[v]){ tree[v]=vec[k][i].second ^ tree[k]; dfs(v); } } } int main(){ scanf("%d",&n); for(int x,y,z,i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); vec[x].push_back(make_pair(y,z)); vec[y].push_back(make_pair(x,z)); } dfs(1); scanf("%d",&m); for(int x,y,i=1;i<=m;i++){ scanf("%d%d",&x,&y); printf("%d\n",tree[x]^tree[y]); } return 0; }
链式前向星 时间快 其实理解了 也是很好写 可读性也挺强
#include<bits/stdc++.h> using namespace std; #define N 100005 #define E 200005 int cnt,dis[E],tree[N],n,m,head[N],to[E],next[E]; bool vis[N]; void dfs(int k){ vis[k]=1; int v; for(int i=head[k];i;i=next[i]){ v=to[i]; if(!vis[v]){ tree[v]=dis[i] ^ tree[k]; dfs(v); } } } int main(){ scanf("%d",&n); for(int x,y,z,i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&z); next[++cnt]=head[x]; to[cnt]=y; head[x]=cnt; dis[cnt]=z; next[++cnt]=head[y]; to[cnt]=x; head[y]=cnt; dis[cnt]=z; } dfs(1); scanf("%d",&m); for(int x,y,i=1;i<=m;i++){ scanf("%d%d",&x,&y); printf("%d\n",tree[x]^tree[y]); } return 0; }