图论

原创 2016年08月30日 21:29:53

图论


图的储存

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)),当数据很大的时候,会比上述复杂度优秀不少。

//堆优化后的dij
struct 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]});
            }
        }
    }   
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

图论遍历问题

  • 2017年03月22日 20:32
  • 360KB
  • 下载

图论常用算法matlab程序

  • 2014年12月11日 22:00
  • 83KB
  • 下载

理论: 图论(5): 无权图的最短路径

概述· 上图表示一个无权图G, 使用每个顶点S 作为输入参数, 我们想要找出从S到所有顶点的最短路径。我们只对包含在路径中的边数有兴趣, 因此在边上不存在权。 显然, 这是赋权最短路径的特殊情形。因...

MATLAB图论程序

  • 2016年03月28日 15:55
  • 9KB
  • 下载

数模培训-图论模型简介.ppt

  • 2015年08月08日 11:20
  • 1.88MB
  • 下载

一笔画问题(图论+广搜)

一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用...

找第K短路 c++ 图论

  • 2013年08月06日 16:23
  • 2KB
  • 下载

基于图论的装配公差建模方法

  • 2012年11月11日 13:02
  • 983KB
  • 下载

图论(二):图的四种最短路径算法

本文总结了图的几种最短路径算法的实现:深度或广度优先搜索算法,弗洛伊德算法,迪杰斯特拉算法,Bellman-Ford算法 1),深度或广度优先搜索算法(解决单源最短路径) 从起始结点开始访...
  • qibofang
  • qibofang
  • 2016年06月06日 13:06
  • 15628

图论的算法与程序设计

  • 2014年01月14日 09:31
  • 3.66MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图论
举报原因:
原因补充:

(最多只允许输入30个字)