图的储存

  对于图的储存是做图论题的基础,图的储存主要有两种方式,一个是邻接表,一个是邻接矩阵。两种储存方式有时候可以通用,但有一些图论题却不能混用。

  邻接矩阵实现方式很简单,直接就是创建一个二维数组G[N][N],对于点x,y,G[x][y]的值就是x->y这一条边的权值。

#include
#define INF 0x3f3f3f3f
using namespace std;
int G[N][N];
int N = 1e4+5;
int main()
{
    int x,y,w;
    int n,m;//图有n个点,有m条边
    cin>>n;
    //对邻接矩阵初始化
   for(int i=0;i<=n;i++)
    {
        for(int j=0;j<=n;j++)
        {
            if(i==j)
                G[i][j]=0;//点i就是点j,权值为零
            else
                G[i][j]=G[j][i]=INF;//点i和点j不连通,也就是i和j的权值无限大(无向图)
                //G[i][j]=INF;有向图
       }
    }
    for(int i=0;i>x>>y>>w;
        G[x][y]=G[y][x]=w;
        //G[x][y]=w;有向图   
    }
    return 0;
}
  邻接矩阵的缺点是时间复杂度为O(n^2),而且n不能大于1e4,否则会报错。不过邻接矩阵在最短路径应用较多,也可以与矩阵快速幂一起解决一些图论问题。

  邻接表有两种实现方式,一种是用STL中的vector容器实现,比较简单,不过数据量如果很大的话建议用数组实现,否则容易超时。

#include
#include
const int N = 1e5+5;
struct Node
{
   int w;
   int y;
};
vector  v[N];
int main()
{
    int x,y,w;
    int n;
    cin>>n;
   for(int i=0;i>x>>y>>w;
     node now;
     now.y=y;
     now.w=w;
     v[x].push_back(now);
      now.y=x;
      v[y].push_back(now);
    }
    return 0;
}

  数组实现

#include
using namespace std;
const int M = 1e6+10;
struct Edge
{
    int u,v,w;
} e[M];
int v[M],w[M],next[M],head[M],edge;//head初始化为-1,模拟邻接表

void init(int n)
{
    fill(v,v+n,0);
    fill(w,w+n,inf);
    fill(next,next+n,-1);
    fill(head,head+n,-1);
    edge = 0;
}
void addedge(int a,int b,int x)//主要如果是无向图的话,每条边要执行两次这个,a,b反过来就行
{
    v[edge]=b;
    w[edge]=x;
    next[edge]=head[a];
    head[a]=edge++;
}
void init(){ memset(head, -1, sizeof(head)); edgenum = 0; }//注意表头的初始化
int main()
{
    int x,y;
    int n;
    init();
    for(int i=0;i



你可能感兴趣的:(算法与数据结构总结及模板)