图的基本操作(遍历,寻找最短路径,最小生成树)

来源:互联网 发布:中国房地产未来知乎 编辑:程序博客网 时间:2024/05/29 10:05
#include<iostream>#include<cstdio>#include<vector>#include<queue>#include<algorithm>#include<cstring>#include<iomanip>    using namespace std;int INF=9999999;template<class T>class MGraph{public:    MGraph(int mSize);    ~MGraph();    bool Insert(int u,int v,int w);    bool Remove(int u,int v);    bool Exist(int u,int v) const;    void DFS();    void BFS();    void Dijkstra(int v,T *d,int *path);    void Floyd(int d[][100],int path[][100]);    void Prim(int k,int *nearest,T *lowcost);private:    int n,e;    T **a;    int Choose(int *d,bool *s);    void DFS(int v,bool *visited);    void BFS(int v,bool *visited);};template<class T>MGraph<T>::MGraph(int mSize){    n=mSize;    e=0;    a=new T*[n];    for(int i=0;i<n;i++)    {        a[i]=new T[n];        for(int j=0;j<n;j++)            a[i][j]=INF;        a[i][i]=0;    }}template<class T>MGraph<T>::~MGraph(){    for(int i=0;i<n;i++)        delete []a[i];    delete []a;}template<class T>bool MGraph<T>::Exist(int u,int v) const{    if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==INF)        return false;    else return true;}template<class T>bool MGraph<T>::Insert(int u,int v,int w){    if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]!=INF)        return false;    a[u][v]=w;    e++;    return true;}template<class T>bool MGraph<T>::Remove(int u,int v){    if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==INF)        return false;    a[u][v]=INF;    e--;    return true;}template<class T>void MGraph<T>::DFS(){    bool *visited=new bool[n];    memset(visited,false,sizeof(visited));    for(int i=0;i<n;i++)        if(visited[i]==false)            DFS(i,visited);    cout<<endl;    delete []visited;}template<class T>void MGraph<T>::DFS(int v,bool *visited){    visited[v]=true;    cout<<v<<" ";    for(int i=0;i<n;i++)    {        if(a[v][i]!=INF&&visited[i]==false)            DFS(i,visited);    }}template<class T>void MGraph<T>::BFS(){    bool *visited=new bool[n];    memset(visited,false,sizeof(visited));    for(int i=0;i<n;i++)        if(visited[i]==false)            BFS(i,visited);    cout<<endl;    delete []visited;}template<class T>void MGraph<T>::BFS(int v,bool *visited){    queue<int> q;    visited[v]=true;    q.push(v);    while(!q.empty())    {        v=q.front();        q.pop();        cout<<v<<" ";        for(int i=0;i<n;i++)            if(visited[i]==false&&a[v][i]!=INF)            {                visited[i]=true;                q.push(i);            }    }}template<class T>void MGraph<T>::Prim(int k,int *nearnest,T *lowcost){    bool *mark=new bool[n];    if(k<0||k>n-1)        return ;    for(int i=0;i<n;i++)    {        nearnest[i]=-1;        lowcost[i]=INF;        mark[i]=false;    }    lowcost[k]=0;    nearnest[k]=k;    mark[k]=true;    int cnt=n-1;    while(cnt--)    {        for(int i=0;i<n;i++)            if(a[k][i]!=INF)                if((!mark[i])&&(lowcost[i]>a[k][i]))                {                    lowcost[i]=a[k][i];                    nearnest[i]=k;                }    T min=INF;    for(int j=0;j<n;j++)        if((!mark[j])&&(lowcost[j]<min))        {            min=lowcost[j];            k=j;        }    mark[k]=true;    }}template<class T>int MGraph<T>::Choose(int *d,bool *s){    int i,minpos;    T min;    min=INF;    for(int i=0;i<n;i++)        if(d[i]<=min&&!s[i])        {            min=d[i];            minpos=i;        }    return minpos;}template<class T>void MGraph<T>::Dijkstra(int v,T *d,int *path){    if(v<0||v>n-1)        return;    bool *s=new bool[n];    for(int i=0;i<n;i++)    {        s[i]=false;        d[i]=a[v][i];        if(i!=v&&d[i]<INF)            path[i]=v;        else            path[i]=-1;    }    s[v]=true;    d[v]=0;    for(int i=1;i<n;i++)    {        cout<<endl;        cout<<"d[]:"<<endl;        for(int k=0;k<n;k++)            cout<<setw(4)<<d[k];        cout<<"path[]:"<<endl;        for(int k=0;k<n;k++)            cout<<setw(4)<<path[k];        int k=Choose(d,s);        s[k]=true;        for(int w=0;w<n;w++)        {            if(!s[w]&&d[k]+a[k][w]<d[w])            {                d[w]=d[k]+a[k][w];                path[w]=k;            }        }    }}template<class T>void MGraph<T>::Floyd(int d[][100],int path[][100]){    for(int i=0;i<n;i++)        for(int j=0;j<n;j++)        {            d[i][j]=a[i][j];            if(i!=j&&a[i][j]<INF)                path[i][j]=i;            else                path[i][j]=-1;        }    cout<<"Before Floyd d and path:"<<endl;    cout<<"d:"<<endl;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            if(d[i][j]==INF)                cout<<setw(4)<<"INF";            else                cout<<setw(4)<<d[i][j];        }        cout<<endl;    }    cout<<"path:"<<endl;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            cout<<setw(4)<<path[i][j];        }        cout<<endl;    }    for(int k=0;k<n;k++)        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)            {                if(d[i][k]+d[k][j]<d[i][j])                {                    d[i][j]=d[i][k]+d[k][j];                    path[i][j]=path[k][j];                }            }    cout<<"After Floyd d and path:"<<endl;    cout<<"d:"<<endl;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            if(d[i][j]==INF)                cout<<setw(4)<<"INF";            else                cout<<setw(4)<<d[i][j];        }        cout<<endl;    }    cout<<"path:"<<endl;    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            cout<<setw(4)<<path[i][j];        }        cout<<endl;    }}int main(){    int n;    cout<<"输入顶点个数:"<<endl;    cin>>n;    MGraph<int> M(n);    cout<<"请选择:1.无向图  2.有向图"<<endl;    int choice;    cin>>choice;    if(choice!=1&&choice!=2)    {        cout<<"错误"<<endl;        return 0;    }    else if(choice==1)    {        cout<<"输入无向边的个数:";    }    else        cout<<"输入有向边的个数: ";    int m;    cin>>m;    if(choice==1)    {        for(int i=0;i<m;i++)        {            int x,y,w;            cin>>x>>y>>w;            M.Insert(x,y,w);            M.Insert(y,x,w);        }    }    else    {        for(int i=0;i<m;i++)        {            int x,y,w;            cin>>x>>y>>w;            M.Insert(x,y,w);        }    }    cout<<"DFS:"<<endl;    M.DFS();    cout<<"BFS:"<<endl;    M.BFS();    int nearest[100];    int lowcost[100];    int flag=0;    M.Prim(0,nearest,lowcost);    for(int i=0;i<n;i++)        if(lowcost[i]==INF)            flag=1;    if(flag==0)    {        cout<<"最小生成树的边集为:"<<endl;        for(int i=0;i<n;i++)            cout<<setw(4)<<nearest[i]<<setw(4)<<i<<setw(4)<<lowcost[i]<<endl;        cout<<endl;    }    else        cout<<"这不是一个连通图"<<endl;    int d[100];    int path[100];    int v,s;    cout<<"输入寻找单元最短路径的起点和终点:"<<endl;    cin>>v>>s;    M.Dijkstra(v,d,path);    int record[100];    if(d[s]==INF)        cout<<"无法到达"<<endl;    else    {        cout<<"最短路径是:"<<d[s]<<endl;        int i=s;        int j=1;        record[0]=s;        while(path[i]!=v)        {            record[j++]=path[i];            i=path[i];        }        record[j++]=v;        reverse(record,record+j);        for(int i=0;i<j;i++)        {            if(i==0)                cout<<record[i];            else                cout<<" ->"<<record[i];        }        cout<<endl;    }    int dd[100][100];    int ppath[100][100];    M.Floyd(dd,ppath);    printf("请输入 起点和终点 ,输入 0 0 停止:\n");    while(scanf("%d%d",&v,&s)==2)    {        if(v==0&&s==0)            break;        if(dd[v][s]==INF)            cout<<"无法到达!"<<endl;        else        {            printf("最短路长度是: %d \n",dd[v][s]);            memset(record,0,sizeof(record));            int j=0;            while(s!=v)            {                record[j++]=s;                s=ppath[v][s];            }            record[j++]=s;            reverse(record,record+j);            printf("路径为:\n");            for(int i=0;i<j;i++)            {                if(i==0)                    printf("%d",record[i]);                else                    printf("->%d",record[i]);            }        }        printf("\nFloyd 请输入 起点和终点 ,输入 0 0 停止:\n");    }    return 0;}


阅读全文
0 0