图的相关算法

原创 2012年03月21日 22:06:04

图的广度优先搜索和深度优先搜索:

#include <iostream>
#include <queue>
#include <stdio.h>
#include <queue>
#include <stdlib.h>
#include <list>
using namespace std;

#define VERTEXNUM 100//最大顶点数
#define INF  65535
enum nodecolor {white,gray,black};
typedef struct node//参见算法导论322
{
    int adjvex;//顶点位置
    struct node *next;//指向下一条边的指针
}EdgeNode;
typedef struct vnode
{
    char vertex;//顶点信息
    EdgeNode *firstedge;//指向第一条依附该顶点的边的指针
    nodecolor color;
    int d;//广度优先中到第一个点的距离,深度优先中被发现的时间
    int f;//深度优先中结束检查此结点的邻接表的时间
    vnode* pi;//父结点
}AdjList[VERTEXNUM];
typedef struct
{
    AdjList vertexs;//邻接表
    int vernum,edgenum;//图中当前的顶点和边数
}Graph;

//建立邻接表
void MakeGraph(Graph *G)
{
    int v1,v2;
    int i,j,k;
    cout<<"请输入图的顶点数和边数"<<endl;
    cin>>G->vernum>>G->edgenum;
    cout<<"请输入顶点信息(顶点号<CR>)每个顶点以回车作为结束:"<<endl;

    for(i=0;i<G->vernum;++i)
    {
        //getchar();
        cin>>G->vertexs[i].vertex;
        G->vertexs[i].firstedge=NULL;//初始第一条边为空
    }

    cout<<"请输入每条边对应的两个顶点的序号(格式为i,j):"<<endl;
    EdgeNode *p;
    for(k=0;k<G->edgenum;k++)
    {
        cin>>i>>j;//读入边<vi,vj>的序号
        p=(node*)malloc(sizeof(node));//生成新的结点
        p->adjvex=j-1;
        p->next=G->vertexs[i-1].firstedge;
        G->vertexs[i-1].firstedge=p;//这3行是插入链表的操作
    }
}

//广度优先遍历
void BFS(Graph *G,vnode *s)
{
    int i;
    queue<vnode *> Q;
    EdgeNode *p;
    vnode *u;
    for(i=0;i<G->vernum;i++)
    {
        G->vertexs[i].d=INF;
        G->vertexs[i].pi=NULL;
        G->vertexs[i].color=white;
    }
    s->color=gray;
    s->d=0;
    s->pi=NULL;
    Q.push(s);
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();//出队
        p=u->firstedge;
        while(p)
        {
            if(G->vertexs[p->adjvex].color==white)
            {
                G->vertexs[p->adjvex].color=gray;
                G->vertexs[p->adjvex].d=u->d+1;
                G->vertexs[p->adjvex].pi=u;
                Q.push(&G->vertexs[p->adjvex]);
            }
            p=p->next;
        }
        u->color=black;
    }
    for(i=0;i<G->vernum;i++) 
    {
        u=&G->vertexs[i];
        cout<<"结点:"<<u->vertex<<"距离:"<<u->d<<"颜色:"<<u->color<<endl;
    }        
}

//深度优先遍历
void DFS_visit(Graph *G,vnode *u);
int t=0;//时间
list<vnode*> L;//用于拓扑排序

void DFS(Graph *G)
{
    int i;
    for(i=0;i<G->vernum;i++)
    {
        G->vertexs[i].d=INF;
        G->vertexs[i].pi=NULL;
        G->vertexs[i].color=white;
    }
    for(i=0;i<G->vernum;i++)
    {
        if(G->vertexs[i].color==white)
            DFS_visit(G,&G->vertexs[i]); 
    }
    for(i=0;i<G->vernum;i++) 
    {
        vnode *u=&G->vertexs[i];
        cout<<"结点:"<<u->vertex<<"开始:"<<u->d<<"结束:"<<u->f<<endl;
    }        
}
void DFS_visit(Graph *G,vnode *u)
{
    EdgeNode *p;
    u->color=gray;
    u->d=++t;
    p=u->firstedge;
    while(p)
    {
       if(G->vertexs[p->adjvex].color==white)
       {
           G->vertexs[p->adjvex].pi=u;
           DFS_visit(G,&G->vertexs[p->adjvex]);
       } 
       p=p->next;
    }
    u->color=black;
    u->f=++t;
    L.insert(L.begin(),u);//用于拓扑排序
}
    
//拓扑排序
list<vnode*>& topological_sort(Graph* G)
{
    DFS(G);
    return L;
}

int main()
{
    int j;
    Graph *G=(Graph *)malloc(sizeof(Graph));
    MakeGraph(G);
    cout<<"请输入广度优先开始遍历的结点的序号:"<<endl;
    cin>>j;
    cout<<"广度优先遍历:"<<endl;
    BFS(G,&G->vertexs[j-1]);
    cout<<"深度优先遍历:"<<endl;
    DFS(G);
    return 0;
}


最小生成树:

//Kruskal

const int maxint = 999999;
typedef struct Road
{
    int c1,c2;//a到b
    int value;//权值
}Road;

int no;
int line;
Road road[100];
int node[101];

bool myCmp(const Road &a,const Road &b)
{
    return (a.value<b.value);
}

int Find_Set(int n)
{
    if(node[n]==-1)
        return n;
    else
        return Find_Set(node[n]);//其实就是沿着树找到根
}

bool Merge(int s1,int s2)
{
    int r1=Find_Set(s1);
    int r2=Find_Set(s2);
    if(r1==r2)//根相同就是属于同一棵树
        return 0;
    if(r1<r2)
        node[r2]=r1;
    else
        node[r1]=r2;
    return 1;
}

int main()
{
    freopen("input.txt","r",stdin);
    memset(node,-1,sizeof(node));
    cout<<"Input the number of the node:";
    cin>>no;
    cout<<"Input the number of the line:";
    cin>>line;
    cout<<"Input the edge:";
    for(int i=0;i<line;++i)
    {
        cin>>road[i].c1>>road[i].c2>>road[i].value;
    }
    sort(road,road+line,myCmp);
    int sum=0,count=0;
    for(int i=0;i<line;++i)
    {
        if(Merge(road[i].c1,road[i].c2))
        {
            count++;
            sum+=road[i].value;
        }
        if(count==no-1)
            break;
    }
    cout<<sum<<endl;
}

//Prim

const int INF=1001;
int no,line;
int arcs[101][101];
int dis[101],vis[101];
int _min;

int main()
{
    freopen("input.txt","r",stdin);

    cout<<"Input the number of the node:";
    cin>>no;
    cout<<"Input the number of the line:";
    cin>>line;

    for(int i=0;i<no;++i)
        for(int j=0;j<no;++j)
            arcs[i][j]=INF;
    cout<<"Input the edge:";
    int p,q,len;//输入p,q两点及路径长度
    for(int i=0;i<line;++i)
    {
        cin>>p>>q>>len;
        if(len<arcs[p-1][q-1])//有重边
        {
            arcs[p-1][q-1]=len;
            arcs[p-1][q-1]=len;//表示无向图
        }
    }
    memset(vis,0,sizeof(vis));
    for(int i=1;i<no;++i)
        dis[i]=arcs[0][i];
    vis[0]=1;
    int sum=0,rec=0;
    dis[0]=0;
    for(int i=1;i<no;++i)
    {
        _min=INF;
        for(int j=0;j<no;++j)
            if(!vis[j]&&dis[j]<_min)
            {
                rec=j;
                _min=dis[j];
            }
        cout<<"min:"<<_min<<endl;
        sum+=_min;
        vis[rec]=1;
        for(int j=0;j<no;++j)
            if(!vis[j]&&arcs[rec][j]<dis[j])
                dis[j]=arcs[rec][j];
    }
    printf("%d\n",sum);
    return 0;
}


图的概念和关于图的几个算法

图是算法中是树的拓展,树是从上xian
  • KangRoger
  • KangRoger
  • 2014年07月19日 17:07
  • 4001

数据结构与算法——图

图 在图中,节点之间的关系是任意的,任意两个节点之间都可能有关系 图的术语巨多无比,接下来给大家总结一下: 图分为有向图、无向图,无向图由定点和边组成,有向图有顶点和弧组成,弧分为弧头、弧尾。 图按...
  • Areay_GK
  • Areay_GK
  • 2016年02月19日 17:05
  • 521

2015年大二上-数据结构-图-1-(1)图基本算法库

图的存储结构主要包括邻接矩阵和邻接表,本算法库提供存储结构的定义,以及用于构造图存储结构、不同结构的转换及显示的代码。算法库采用程序的多文件组织形式,包括两个文件:      1.头文件:G...
  • Annpion
  • Annpion
  • 2016年01月23日 12:03
  • 847

图遍历算法的应用

图遍历算法的应用
  • zj20320
  • zj20320
  • 2016年08月05日 18:34
  • 371

数据结构与算法--图

数据结构与算法–图 线性表的每个元素有线性关系,每个数据元素只有一个直接前去和一个直接后继。树的数据元素之间有着明细那的层次关系,并且每层上的数据元素可能和下一层中多个元素相关,但只能和上一层中一个...
  • Gavin_Yueyi
  • Gavin_Yueyi
  • 2015年10月15日 19:07
  • 1931

全局空间自相关算法:Join Count

ArcGIS里面,全局空间自相关只提供了一个Moran's I方法,当然要说一招鲜吃遍天也是可以的,不过关于全局自相关还是有不少其他的方法的,这次给大家介绍一种更加简单并且容易理解的全局空间自相关方...
  • allenlu2008
  • allenlu2008
  • 2015年11月17日 23:37
  • 5716

【Cactus仙人掌图】仙人掌DP学习笔记

我们从例题入手来考虑仙人掌上DP的一般规律叭.Ex 1.仙人掌上的单源最短路问题 联想树上最短路,由于路径的唯一性可以直接做一遍O(n)的搜索.但是仙人掌上显然不具备路径的唯一性这种性质. 那么我...
  • CreationAugust
  • CreationAugust
  • 2015年08月27日 10:30
  • 2215

立体匹配算法介绍

首先介绍一篇比较好的介绍立体匹配的综述性文章:http://wenku.baidu.com/view/5b359d7d5acfa1c7aa00cc7b.html 而后有一个较好的介绍立体匹配的P...
  • MySniper11
  • MySniper11
  • 2013年02月27日 16:27
  • 19248

图算法之拓扑排序

拓扑排序是对有向无圈图的顶点的一种排序,它使得如果存在一条从vi到vj的路径,那么在排序中Vj出现在Vi后面。一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后我们显示该顶点,并将它和它的...
  • u012000209
  • u012000209
  • 2015年08月11日 22:30
  • 1410

图的相关算法

图的基础相关算法有BFS,DFS,拓扑排序, 强连通分支,kruskal,prim,Bellman-Ford,Dijkstra。这些算法思想不难,就是代码容易忘记,所以将代码写在这里,以备复习。本文的...
  • f_x_q
  • f_x_q
  • 2013年08月12日 10:05
  • 831
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:图的相关算法
举报原因:
原因补充:

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