图论

来源:互联网 发布:php布尔类型 编辑:程序博客网 时间:2024/05/21 18:43

  • 图论
    • 图的储存
      • 邻接矩阵
      • 邻接表
    • 最短路径
      • floyd
      • dijkstra
    • 最小生成树
      • Prim

图论


图的储存

1.邻接矩阵

2.邻接表

struct tyc{int x,t,l,ne;} e[M];int v[N];void put (int x,int y,int l){    num++;e[num]={x,y,l,v[x]};    v[x]=num;}//枚举点x的所有出边for(int i=v[x];i;i=e[i].ne) i是出边

最短路径

floyd

//复杂度O(n^3)for(int k=1;k<=n;k++)    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);

dijkstra

需要注意的是:dijkstra无法用于处理带负权值的图

dijkstra的主要思路是分蓝白点,确定最短路长度的是白点,蓝点反之。
复杂度是相对比较优秀的O(n^2);

    int S=1;    memset(vis,0,sizeof(vis));    for(int i=1;i<=n;i++){        if(dis[S][i]!=-1) d[i]=dis[S][i];        else d[i]=inf;    }    int k=0;    vis[S]=true;    d[0]=inf;    for(int i=1;i<n;i++){        int mn=inf,k=0;        for(int j=1;j<=n;j++)            if(!vis[j] && d[j]<=mn)  mn=d[j],k=j;//用变量mn筛出此时距离S最近的点        vis[k]=1;        for(int j=1;j<=n;j++){            if(!vis[j] && dis[k][j]!=-1)                d[j]=min(d[j],dis[k][j]);        }    }

上述代码,如果加上常数,其复杂度应是O(2*n^2)。
值的注意的是,通过堆进行优化的dijkstra复杂度更加优秀,可以达到O(n*(logn+n)),当数据很大的时候,会比上述复杂度优秀不少。

//堆优化后的dijstruct tyc {    int id,v;//v 表示上文中的d[x]    friend bool operator < (tyc a,tyc b) {        return a.v>b.v;    } };priority_queue<tyc> que;void Dijkstra(){    int S=1;    memset(vis,0,sizeof(vis));    for(int i=1;i<=n;i++){        if(dis[S][i]!=-1) d[i]=dis[S][i];        else d[i]=inf;    }    que.push((tyc){1,0});    rep(i,1,n){        que.push((tyc){i,d[i]});    }    int x,y;    d[0]=inf;    while(!que.empty()){        x = que.top().id, y = que.top().v;        que.pop();        if(vis[x]) continue;        vis[x]=1;        for(int j=1;j<=n;j++) {            if(vis[j]) continue;            if(dis[x][j]!=-1 && dis[x][j] < d[j]) {                d[j] = dis[x][j];                que.push((tyc){j,d[j]});            }        }    }}

最小生成树

Prim

基本思路与Dijkstra相同

int Prim(){     int ans=0;    int S=1;    memset(vis,0,sizeof(vis));    for(int i=1;i<=n;i++){        if(dis[S][i]!=-1) d[i]=dis[S][i];        else d[i]=inf;    }    int k=0;    vis[S]=true;    d[0]=inf;    for(int i=1;i<n;i++){        int mn=inf,k=0;        for(int j=1;j<=n;j++)            if(!vis[j] && d[j]<=mn)  mn=d[j],k=j;//用变量mn筛出此时距离S最近的点        vis[k]=1;        ans+=d[k];//!!!!!!!!!!!        for(int j=1;j<=n;j++){            if(!vis[j] && dis[k][j]!=-1)                d[j]=min(d[j],dis[k][j]);        }    }    return ans;}

堆优化版:

struct tyc {    int id,v;//v 表示上文中的d[x]    friend bool operator < (tyc a,tyc b) {        return a.v>b.v;    } };priority_queue<tyc> que;int Prim(){     int ans=0;    int S=1;    memset(vis,0,sizeof(vis));    for(int i=1;i<=n;i++){        if(dis[S][i]!=-1) d[i]=dis[S][i];        else d[i]=inf;    }    que.push((tyc){1,0});    rep(i,1,n){        if(d[i]==inf) continue;        que.push((tyc){i,d[i]});    }    int x,y;    d[0]=inf;    while(!que.empty()){        x = que.top().id, y = que.top().v;        que.pop();        if(vis[x]) continue;        vis[x]=1;        ans+=y;        for(int j=1;j<=n;j++) {            if(vis[j]) continue;            if(dis[x][j]!=-1 && dis[x][j] < d[j]) {                d[j] = dis[x][j];                que.push((tyc){j,d[j]});            }        }    }   
0 0
原创粉丝点击