zoukankan      html  css  js  c++  java
  • 树/图的存储方式

     

    GeneralLiu

     

    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
    ",tree[x]^tree[y]);
        }
        return 0;
    }
    View Code

    链式前向星 时间快 其实理解了 也是很好写 可读性也挺强

    #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
    ",tree[x]^tree[y]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    转载:linux or unit 连接 windows的远程桌面-rdesktop(略有修改)
    Excel技巧
    Linux实用配置(ubuntu)
    转载:VMware linux 虚拟机中修改MAC地址
    windows技巧
    cdoj1099
    hdu1160(问题)
    c#学习笔记
    hdu1176
    qsort(),sort() scanf();
  • 原文地址:https://www.cnblogs.com/1227xq/p/6808088.html
Copyright © 2011-2022 走看看