关于图的一个小总结

/*图*/
/*1.遍历*/
/*(1).广度优先遍历,利用visit数组以及入栈和出栈*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
class TU
{
private:
    int vertex;
    int spot;
    int index;
    int str[Max_Size][Max_Size];
    int visit[Max_Size];
public:
    TU()
    {
        vertex=spot=0;
        index=-1;
    }
    ~TU(){}
    void creat(int n,int m)
    {
        spot=n;//点
        vertex=m;//边
        for(int i=0;i<spot;i++)
        {
            for(int j=0;j<spot;j++)
            {
                str[i][j]=0;
            }
        }
        for(int i=0;i<spot;i++)
        {
            visit[i]=0;
        }
        while(++index<vertex)
        {
            int i,j;
            cin>>i>>j;
            str[i][j]=str[j][i]=1;
        }
    }
    void pop(int n)
    {
        int front=0,area=0;
        int node[Max_Size]={0};
        cout<<n<<" ";
        visit[n]=1;
        node[front++]=n;//入栈
        while(front!=area)
        {
            int s=node[area++];//出栈
            for(int i=0;i<spot;i++)
            {
                if(str[s][i]==1&&visit[i]!=1)
                {
                    cout<<i<<" ";
                    node[front++]=i;
                    visit[i]=1;
                }
            }
        }
    }
};


int main()
{
    int n,m,a;
    cin>>n>>m>>a;
    TU p;
    p.creat(n,m);
    p.pop(a);
}*/
/*(2).深度优先遍历*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
class TU
{
private:
    int vertex;
    int spot;
    int index;
    int str[Max_Size][Max_Size];
    int visit[Max_Size];
public:
    TU()
    {
        vertex=spot=0;
        index=-1;
    }
    ~TU(){}
    void creat(int n,int m)
    {
        spot=n;//点
        vertex=m;//边
        for(int i=0;i<spot;i++)
        {
            for(int j=0;j<spot;j++)
            {
                str[i][j]=0;
            }
        }
        for(int i=0;i<spot;i++)
        {
            visit[i]=0;
        }
        while(++index<vertex)
        {
            int i,j;
            cin>>i>>j;
            str[i][j]=str[j][i]=1;
        }
    }
    void pop(int v)
    {
        visit[v]=1;
        cout<<v<<" ";
        for(int i=0;i<spot;i++)
        {
            if(str[v][i]==1&&visit[i]!=1)
            {
                pop(i);
            }
        }
    }
};


int main()
{
    int n,m,a;
    cin>>n>>m>>a;
    TU p;
    p.creat(n,m);
    p.pop(a);
}*/
/*注:深度与广度遍历出来的结果不一样,深度为前序,广度为层序
比如:4 4 3 0 1 1 2 2 3 1 3结果不一样 ,深度为3102 广度为3120*/
/*2.最小生成树 Prim 和 Kruskal 带有权值*/
/*(1)Prim 算法 利用了结构体*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
struct ShortEdge
{
    int lowcost;//权值
    int adjvex;//最短边
};
int findmin(ShortEdge shortedge[],int l)
{
    int min=10000;
    int t=0;
    for(int i=0;i<l;i++)
    {
        if(shortedge[i].lowcost<min&&shortedge[i].lowcost!=0)
        {
            min=shortedge[i].lowcost;
            t=i;
        }
    }
    return t;
}
class Prim
{
private:
    int vertex;
    int spot;
    int index;
    int str[Max_Size][Max_Size];
    ShortEdge shortedge[Max_Size];
public:
    Prim()
    {
        vertex=spot=0;
        index=-1;
    }
    ~Prim(){}
    void creat(int n,int m)
    {
        spot=n;//点
        vertex=m;//边
        for(int i=0;i<spot;i++)
        {
            for(int j=0;j<spot;j++)
            {
                if(i==j)
                {
                    str[i][j]=0;
                    continue;
                }
                str[i][j]=10000;
            }
        }
        while(++index<vertex)
        {
            int i,j,a;
            cin>>i>>j>>a;
            str[i][j]=str[j][i]=a;
        }
    }
    void pop(int v)
    {
        for(int i=0;i<spot;i++)
        {
            shortedge[i].lowcost=str[i][v];
            shortedge[i].adjvex=v;
        }
        shortedge[v].lowcost=0;
        cout<<v<<" ";
        for(int i=1;i<spot;i++)
        {
            int k=findmin(shortedge,spot);//找到最小权值边
            cout<<k<<" ";
            shortedge[k].lowcost=0;
            for(int i=0;i<spot;i++)
            {
                if(shortedge[i].lowcost>str[i][k])
                {
                    shortedge[i].lowcost=str[i][k];
                    shortedge[i].adjvex=k;
                }
            }
        }
    }
};


int main()
{
    int n,m,a;
    cin>>n>>m>>a;
    Prim p;
    p.creat(n,m);
    p.pop(a);
}*/
/*(2).Kruskal算法 注:1.有对结构体的排序从小到大 2利用parent数组,找到是否能构成一个圆*/
/*!!!!!!放弃!!!!!!!!!,先弄下面的*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
struct ShortEdge
{
    int lowcost;//权值
    int adjvex;//最短边
};
int findmin(ShortEdge shortedge[],int l)
{
    int min=10000;
    int t=0;
    for(int i=0;i<l;i++)
    {
        if(shortedge[i].lowcost<min&&shortedge[i].lowcost!=0)
        {
            min=shortedge[i].lowcost;
            t=i;
        }
    }
    return t;
}
class Prim
{
private:
    int vertex;
    int spot;
    int index;
    int str[Max_Size][Max_Size];
    ShortEdge shortedge[Max_Size];
public:
    Prim()
    {
        vertex=spot=0;
        index=-1;
    }
    ~Prim(){}
    void creat(int n,int m)
    {
        spot=n;//点
        vertex=m;//边
        for(int i=0;i<spot;i++)
        {
            for(int j=0;j<spot;j++)
            {
                if(i==j)
                {
                    str[i][j]=0;
                    continue;
                }
                str[i][j]=10000;
            }
        }
        while(++index<vertex)
        {
            int i,j,a;
            cin>>i>>j>>a;
            str[i][j]=str[j][i]=a;
        }
    }
    void pop(int v)
    {
        for(int i=0;i<spot;i++)
        {
            shortedge[i].lowcost=str[i][v];
            shortedge[i].adjvex=v;
        }
        shortedge[v].lowcost=0;
        cout<<v<<" ";
        for(int i=1;i<spot;i++)
        {
            int k=findmin(shortedge,spot);//找到最小权值边
            cout<<k<<" ";
            shortedge[k].lowcost=0;
            for(int i=0;i<spot;i++)
            {
                if(shortedge[i].lowcost>str[i][k])
                {
                    shortedge[i].lowcost=str[i][k];
                    shortedge[i].adjvex=k;
                }
            }
        }
    }
};


int main()
{
    int n,m,a;
    cin>>n>>m>>a;
    Prim p;
    p.creat(n,m);
    p.pop(a);
}*/
/*3.最短路径 Dijkstra 和 Floyd 注:此时的图为有向图 单向,或者看清题干,有时为单向,有时为双向,下面的代码为单向*/
/*(1)Floyd算法 注:利用三重循环*/
/*
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size = 100;
class Floyd
{
private:
    int vertex;
    int spot;
    int index;
    int str[Max_Size][Max_Size];
public:
    Floyd()
    {
        vertex = spot = 0;
        index = -1;
    }
    ~Floyd() {}
    void creat(int n, int m)
    {
        spot = n; //点
        vertex = m; //边
        for(int i = 0; i < spot; i++)
        {
            for(int j = 0; j < spot; j++)
            {
                if(i == j)
                {
                    str[i][j] = 0;
                    continue;
                }
                str[i][j] = 10000;
            }
        }
        while(++index < vertex)
        {
            int i, j, a;
            cin >> i >> j >> a;
            str[i][j] = a;
        }
    }
    void pop()
    {
        int v1, v2;
        cin >> v1 >> v2;
        for(int i = 0; i < spot; i++)
        {
            for(int j = 0; j < spot; j++)
            {
                for(int k = 0; k < spot; k++)
                {
                    if(str[i][j] > str[i][k] + str[k][j])
                    {
                        str[i][j] = str[i][k] + str[k][j];
                    }
                }
            }
        }
        cout << str[v1][v2];
    }
};


int main()
{
    int n, m;
    cin >> n >> m;
    Floyd p;
    p.creat(n, m);
    p.pop();
}*/
/*(2)Dijkstra*/
/*!!!!!!!没有写!!!!!!!!*/

/*3.关键路径 拓扑排序*/

/*拓扑排序*/
/*
/*1.思想:输出没有入度的顶点
2.构造:采用邻接表的方法构造图
  对没有入度的顶点可以设置入栈的操作*/
#include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int Max_Size=100;
/*邻接表的构造*/
struct ArcNode//定义边表结点
{
    int adjvex;//邻接点域
    ArcNode *next;
};
struct VertexNode//定义顶点表结点
{
    int vertex;
    int in;//入度
    ArcNode *firstedge;
};
class ALGraph
{
private:
    VertexNode adjlist[Max_Size];
    int spot,vertex,index;
    int front,area;
    int str[Max_Size];
public:
    ALGraph()
    {
        spot=vertex=front=area=0;
        index=-1;
    }
    ~ALGraph(){}
    void creatList(int n,int m)//构造邻接表
    {
        spot=n;
        vertex=m;
        for(int i=0;i<spot;i++)
        {
            adjlist[i].vertex=i;
            adjlist[i].in=0;
            adjlist[i].firstedge=NULL;
        }
        while(++index<vertex)
        {
            int i,j;
            cin>>i>>j;
            ArcNode *s=new ArcNode;
            s->adjvex=j;
            s->next=adjlist[i].firstedge;
            adjlist[i].firstedge=s;
            adjlist[j].in++;
        }
    }
    void TopSort()//利用入栈出栈
    {
        for(int i=0;i<spot;i++)
        {
            if(adjlist[i].in==0)
            {
                str[front++]=i;
            }
        }
        while(front!=0)
        {
            int k=str[--front];
            cout<<adjlist[k].vertex<<" ";area++;
            ArcNode *p=adjlist[k].firstedge;
            while(p!=NULL)
            {
                int j;
                j=p->adjvex;
                adjlist[j].in--;
                if(adjlist[j].in==0)
                {
                    str[front++]=j;
                }
                p=p->next;
            }
        }
        if(area<spot)
        {
            cout<<"有回路"<<endl;
        }
    }
};
int main()
{
    ALGraph p;
    p.creatList(6,9);
    p.TopSort();
    return 0;

}*/

/*关键路径

/*
思路:(len为边的权值)
事件最早发生时间:ve[k](ve为点),即求出到达该点最长的路径
ve[0]=0;
ve[k]=max{ve[k]+len<vj,vk>}
事件最迟发生时间:vl[k](vl为点),即从后面求,找到最小的路径
vl[n-1]=ve[n-1];
vl[k]=min{vl[j]-len<vk,vj>}
活动最早开始的时间:ee[i](ee为边),即等于该边的始点
ee[i]=ve[k] 即每条边的起点
活动最迟开始的时间:el[i](el为边),即等于该边的终点减去边的权值
el[i]=vl[i]-len<vk,vj>;
关键路径为:ee[i]==el[i]
*/
#include<string.h>
#include<iostream>
#include<stdlib.h>




const int Max_Size=100;




using namespace std;




struct Vel
{
    int from,to;
    int weight;
};
class AOE
{
private:
    int spot,vertex;
    int index;
    int node[Max_Size][Max_Size];
    int ve[Max_Size],vl[Max_Size];
    int ee[Max_Size],el[Max_Size];
    Vel vel[Max_Size];
public:
    AOE()
    {
        spot=vertex=0;
        index=-1;
    }
    ~AOE(){}
    void push(int n,int m)
    {
        spot=n;
        vertex=m;
        for(int i=0;i<spot;i++)
        {
            for(int j=0;j<spot;j++)
            {
                node[i][j]=-1;
            }
        }
        while(++index<vertex)
        {
            int i,j,a;
            cin>>i>>j>>a;
            node[i][j]=a;
            vel[index].from=i;
            vel[index].to=j;
            vel[index].weight=a;
        }
    }
    int k;
    void bulidve()//建立ve,即事件最早发生的时间
    {
        ve[0]=0;
        for(int i=1;i<spot;i++)
        {
            ve[i]=0;
            int max=0;
            for(int j=0;j<spot;j++)
            {
                if(node[j][i]+ve[j]>max&&node[j][i]!=-1)
                {
                    max=node[j][i]+ve[j];
                }
            }
            ve[i]=max;
        }
    }
    void bulidvl()//建立事件最迟发生的时间
    {
        vl[spot-1]=ve[spot-1];
        for(int i=spot-2;i>=0;i--)
        {
            vl[i]=0;
            int min=10000;
            for(int j=spot-1;j>=0;j--)
            {
                if(vl[j]-node[i][j]<min&&node[i][j]!=-1)
                {
                    min=vl[j]-node[i][j];
                }
            }
            vl[i]=min;
        }
    }
    void bulidee()//建立活动最早开始时间
    {
        for(int i=0;i<vertex;i++)
        {
            int k=vel[i].from;
            ee[i]=ve[k];
        }
    }
    void bulidel()
    {
        for(int i=vertex-1;i>=0;i--)
        {
            int k=vel[i].to;
            el[i]=vl[k]-vel[i].weight;
        }
    }
    void pop()//ee==el时,该边为关键路径
    {
        int a[100]={0},k=0;
        for(int i=0;i<vertex;i++)
        {
            if(ee[i]==el[i])
            {
                a[k]=i;
                cout<<i<<" ";
                k++;
            }
        }
    }
};
int main()
{
    AOE p;
    p.push(9,11);
    p.bulidve();
    p.bulidvl();
    p.bulidee();
    p.bulidel();
    p.pop();
    return 0;
}*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值