////储存结构:邻接矩阵
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "queue.cpp"
using namespace std;

#define INF 1000000
#define MAX_NAME 12
#define MAX_INFO 26
#define MAX_VERTEX_NUM 26

enum GraphKind{DG,DN,UDG,UDN};

typedef int VRType;
typedef char VertexType[12];

bool vis[MAX_VERTEX_NUM];

typedef struct
{
    VRType adj; //顶点关系类型。
    //InfoType *info; //该弧相关信息指针
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

struct MGraph
{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs; //邻接矩阵
    int vexnum,arcnum;//顶点数,弧数
    GraphKind kind;//图的种类标志
};

int LocateVex(MGraph G, VertexType u)
{
    //初始条件:图G存在,u和G中顶点有相同特征
    //操作结构:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
    int i;
    for(i = 0; i < G.vexnum; i++){
        if(strcmp(u,G.vexs[i]) == 0)
        return i;
    }
    return -1;
}

void Degree(MGraph G)
{
    //求顶点的度
    VertexType u;
    int ans = 0;
    printf("请输入相应顶点,来计算该顶点的度:");
    scanf("%s",u);
    int i = LocateVex(G,u);
    if(i == -1){
        printf("该顶点不存在
");
    }
    else{
        for(int k = 0; k < G.vexnum; k++){
            if(G.arcs[i][k].adj){
                ans++;
            }
            if(G.arcs[k][i].adj && G.kind == DG){
                ans++;
            }
        }
        printf("Degree:%d
",ans);
    }
}

int FirstAdjVex(MGraph G,VertexType v)
{
    //返回v的第一个邻接顶点的序号。若顶点在G中没有邻接顶点,返回-1
    int i,j = 0,k;
    k = LocateVex(G,v);
    //if(G.kind % 2){
        ////网
        //j = INFINITY;
    //}
    for(i = 0; i < G.vexnum; i++){
        if(G.arcs[k][i].adj != j){
            return i;
        }
    }
    return -1;
}

int NextAdjVex(MGraph G,VertexType v,VertexType w)
{
    //返回v的(相对于w)下一个邻接顶点的序号,若w是v的最后一个邻接顶点,则返回-1
    int i,j = 0,k1,k2;
    k1 = LocateVex(G,v);
    k2 = LocateVex(G,w);
    //if(G.kind % 2){
        ////网
        //j = INFINITY;
    //}
    for(i = k2 + 1; i < G.vexnum; i++){
        if(G.arcs[k1][i].adj != j){
            return i;
        }
    }
    return -1;
}

void DFS(MGraph G,int v) //深度优先搜索
{
    int w;
    vis[v] = true;
    printf("%s ",G.vexs[v]);
    w = FirstAdjVex(G,G.vexs[v]);
    while(w >= 0){
        if(!vis[w]){
            DFS(G,w);
        }
        w = NextAdjVex(G,G.vexs[v],G.vexs[w]);
    }
}

void DFSTraverse(MGraph G)
{
    int v;
    memset(vis,false,sizeof(vis));
    for(v = 0; v < G.vexnum; v++){
        if(!vis[v]){
            DFS(G,v);
        }
    }
    printf("
");
}

void BFSTraverse(MGraph G)
{
    int v,u,w;
    LinkQueue Q;
    InitQueue(Q);
    memset(vis,false,sizeof(vis));
    for(v = 0; v < G.vexnum; v++){
        //如果是连通图,v = 0就遍历全图
        if(!vis[v]){
            vis[v] = true;
            printf("%s ",G.vexs[v]);
        }
        EnQueue(Q,v);
        while(!QueueEmpty(Q)){
            DeQueue(Q,u);
            w = FirstAdjVex(G,G.vexs[u]);
            while(w >= 0){
                if(!vis[w]){
                    vis[w] = true;
                    printf("%s ",G.vexs[w]);
                    EnQueue(Q,w);
                }
                w = NextAdjVex(G,G.vexs[u],G.vexs[w]);
            }
        }
    }
    printf("
");
}

void CreateUDG(MGraph &G) //构造无向图
{
    int i,j,k,l;//IncInfo;
    char s[MAX_INFO];
    VertexType va,vb;
    printf("请输入无向图G的顶点数,边数。
");
    scanf("%d%d",&G.vexnum,&G.arcnum);
    printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    for(i = 0; i < G.vexnum; i++){
        scanf("%s",G.vexs[i]);
    }
    for(i = 0; i < G.vexnum; i++){
        for(j = 0; j < G.vexnum; j++){
            G.arcs[i][j].adj = 0;
            //G.arcs[i][j].info = NULL;
        }
    }
    printf("请输入%d条边的顶点1,顶点2:
",G.arcnum);
    for(k = 0; k < G.arcnum; k++){
        printf("Case %d:",k + 1);
        scanf("%s %s",va,vb);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        G.arcs[i][j].adj = G.arcs[j][i].adj = 1;
        //if(IncoInfo){}
    }
    G.kind = UDG;
}

void CreateDG(MGraph &G) //构造有向图
{
    int i,j,k,l;//IncInfo;
    char s[MAX_INFO];
    VertexType va,vb;
    printf("请输入有向图G的顶点数,边数。
");
    scanf("%d%d",&G.vexnum,&G.arcnum);
    printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    for(i = 0; i < G.vexnum; i++){
        scanf("%s",G.vexs[i]);
    }
    for(i = 0; i < G.vexnum; i++){
        for(j = 0; j < G.vexnum; j++){
            G.arcs[i][j].adj = 0;
            //G.arcs[i][j].info = NULL;
        }
    }
    printf("请输入每条弧的弧尾和弧头:
");
    for(k = 0; k < G.arcnum; k++){
        printf("Case %d:",k + 1);
        scanf("%s %s",va,vb);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        G.arcs[i][j].adj = 1;
        //if(IncoInfo){}
    }
    G.kind = DG;
}
void Prt(MGraph G){
    int i,j;
    printf("vexnum :%d, arcnum :%d.

",G.vexnum,G.arcnum);
    printf("Vexlist:
");
    for(i = 0; i < G.vexnum; i++){
        printf("        v(%d):%s
",i,G.vexs[i]);
    }
    //Matrix  
    printf("
Matrix:
   ");
    for(i = 0; i < G.vexnum; i++){
        printf("(%d) ",i);
    }
    printf("
");
    for(i = 0; i < G.vexnum; i++){
        printf("(%d) ",i);
        for(j = 0; j < G.vexnum; j++){
            printf("%d ",G.arcs[i][j].adj);
        }
        printf("
");
    }
}

int main()
{
    MGraph G;
    //CreateDG(G);//创建有向图
    CreateUDG(G); //创建无向图
    Prt(G);
    //Degree(G);
    //DFSTraverse(G);
    BFSTraverse(G);

    return 0;
}
////储存方式:邻接表
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "queue.cpp"
using namespace std;

#define MAX_NAME 12
#define MAX_INFO 20
#define MAX_VERTEX_NUM 20

int deg[MAX_VERTEX_NUM]; //存各顶点度
bool vis[MAX_VERTEX_NUM]; //dfs遍历标记

enum GraphKind{DG,DN,UDG,UDN};

typedef char VertexType[12];

struct ArcNode
{
    int adjvex; //该弧所指向的顶点的位置
    ArcNode *nextarc; //指向下一条弧的指针
    //InfoType *info; //网的权值指针
};//表节点

typedef struct
{
    VertexType data; //顶点信息
    ArcNode *firstarc; //第一个表节点的地址,指向第一条依附该顶点的弧指针
}VNode,AdjList[MAX_VERTEX_NUM]; //头节点

struct ALGraph
{
    AdjList vertices;
    int vexnum,arcnum; //图的当点顶点数和弧数
    int kind; //图的种类标志
};

//返回u的顶点序号,若图中不含u,返回-1
int LocateVex(ALGraph G,VertexType u)
{
    int i;
    for(i = 0; i < G.vexnum; i++){
        if(strcmp(u,G.vertices[i].data) == 0)
        return i;
    }
    return -1;
}

//返回v的第一个邻接顶点的序号,若图中无邻接顶点,返回-1
int FirstAdjVex(ALGraph G,VertexType v){
    int i = LocateVex(G,v);
    ArcNode *p = G.vertices[i].firstarc;
    if(p){
        return p->adjvex;
    }
    else{
        return -1;
    }
}

//返回v的(相对于w的)下一个邻接顶点的序号。若w是v的最后一个邻接顶点,则返回-1
int NextAdjVex(ALGraph G,VertexType v,VertexType w){
    int i = LocateVex(G,v);
    int j = LocateVex(G,w);
    ArcNode *p = G.vertices[i].firstarc;
    while(p){
        if(p->adjvex == j) break;
        p = p->nextarc;
    }
    if(!p || !p->nextarc){ //没找到w或w是最后一个邻接点
                          return -1;
                         }
    else{
        return (p->nextarc)->adjvex;
    }
}

void ListInsert(VNode &p,ArcNode e) //头插法
{
    ArcNode *q = (ArcNode *)malloc(sizeof(ArcNode));
    q->adjvex = e.adjvex;
    q->nextarc = p.firstarc;
    p.firstarc = q;
}

//求图中各顶点的度
void Degree(ALGraph G){
    int i;
    VertexType u;
    memset(deg,0,sizeof(deg));
    for(i = 0; i < G.vexnum; i++){
        ArcNode *p = G.vertices[i].firstarc;
        while(p){
            deg[i]++;
            deg[p->adjvex]++;
            p = p->nextarc;
        }
    }
    printf("请输入相应顶点,来计算该顶点的度:");
    scanf("%s",u);
    i = LocateVex(G,u);
    if(G.kind == UDG){
        printf("Degree:%d
",deg[i] / 2);
    }
    else{
        printf("Degree:%d
",deg[i]);
    }

}

//DG DN UDG UDN 有向图 有向网 无向图 无向网
//创建有向图
void CreateDG(ALGraph &G){
    int i,j,k;
    VertexType va,vb;
    ArcNode e;
    printf("-----建立有向图-----
");
    printf("请输入图的顶点数,边数:");
    scanf("%d%d",&G.vexnum,&G.arcnum);
    printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    for(i = 0; i < G.vexnum; i++){
        scanf("%s",G.vertices[i].data);
        G.vertices[i].firstarc = NULL;
    }
    printf("请输入每条弧的弧尾和弧头:
");
    for(k = 0; k < G.arcnum; k++){
        printf("Case %d:",k + 1);
        scanf("%s%s",va,vb);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        //e.info = NULL; //图无权
        e.adjvex = j;
        ListInsert(G.vertices[i],e);
    }
    G.kind = DG;
}

//创建无向图
void CreateUDN(ALGraph &G){
    int i,j,k;
    VertexType va,vb;
    ArcNode e;
    printf("-----建立无向图-----
");
    printf("请输入图的顶点数,边数:");
    scanf("%d%d",&G.vexnum,&G.arcnum);
    printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    for(i = 0; i < G.vexnum; i++){
        scanf("%s",G.vertices[i].data);
        G.vertices[i].firstarc = NULL;
    }
    printf("请输入每条弧的两个顶点:
");
    for(k = 0; k < G.arcnum; k++){
        printf("Case %d:",k + 1);
        scanf("%s%s",va,vb);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        //e.info = NULL; //图无权
        e.adjvex = i;
        ListInsert(G.vertices[j],e);
        e.adjvex = j;
        ListInsert(G.vertices[i],e);
    }
    G.kind = UDG;
}

//深度优先搜索
void DFS(ALGraph G,int v){
    int w;
    vis[v] = true;
    printf("%s ",G.vertices[v].data); //访问第v个顶点

    w = FirstAdjVex(G,G.vertices[v].data);
    while(w >= 0){
        if(!vis[w]){
            DFS(G,w);
        }
        w = NextAdjVex(G,G.vertices[v].data,G.vertices[w].data);
    }
    //for(w = FirstAdjVex(G,G.vertices[v].data); w >= 0; w = NextAdjVex(G,G.vertices[v].data,G.vertices[w].data));{
        //if(!vis[w]){
            //DFS(G,w);
        //}
    //}
}

//对图做深度优先遍历
void DFSTraverse(ALGraph G){
    int v;
    memset(vis,false,sizeof(vis));
    for(v = 0; v < G.vexnum; v++){
        if(!vis[v]){
            DFS(G,v);//对尚未访问的顶点调用DFS
        }
    }
    printf("
");
}

//对图做广度优先搜索
void BFSTraverse(ALGraph G)
{
    int v,u,w;
    LinkQueue Q;
    InitQueue(Q);
    memset(vis,false,sizeof(vis));
    for(v = 0; v < G.vexnum; v++){ 
        //如果是连通图,v = 0就遍历全图
        if(!vis[v]){
            vis[v] = true;
            printf("%s ",G.vertices[v].data);
        }
        EnQueue(Q,v);
        while(!QueueEmpty(Q)){
            DeQueue(Q,u); //队头元素出队,并置为u
            w = FirstAdjVex(G,G.vertices[u].data);
            while(w >= 0){
                if(!vis[w]){
                    vis[w] = true;
                    printf("%s ",G.vertices[w].data);
                    EnQueue(Q,w);//入队
                }
                w = NextAdjVex(G,G.vertices[u].data,G.vertices[w].data);
            }
        }
    }
    printf("
");
}

//打印该图的储存形式
void Prt(ALGraph G)
{
    int i;
    printf("vexnum :%d, arcnum :%d.

",G.vexnum,G.arcnum);
    printf("VexList:
");
    for(i = 0; i < G.vexnum; i++){
        printf("        v(%d):%s|",i,G.vertices[i].data);
        ArcNode *p = G.vertices[i].firstarc;
        while(p){
            printf("->%d",p->adjvex);
            p = p->nextarc;
        }
        printf("
");
    }
}

int main()
{
    ALGraph G;
    //CreateDG(G); //建立有向图
    CreateUDN(G);  //建立无向图
    Prt(G);
    //Degree(G);
    //DFSTraverse(G);
    BFSTraverse(G);

    return 0;
}
////储存结构:邻接矩阵
//功能:prim算法求最小生成树
#define INF 1000000
#define MAX_NAME 12
#define MAX_INFO 26
#define MAX_VERTEX_NUM 26

enum GraphKind {DG,DN,UDG,UDN};

typedef int VRType;
//typedef char VertexType[12];
typedef int VertexType;


typedef struct
{
    VRType adj; //顶点关系类型。
    //InfoType *info; //该弧相关信息指针
} ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

struct MGraph
{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs; //邻接矩阵
    int vexnum,arcnum;//顶点数,弧数
    GraphKind kind;//图的种类标志
};

//记录从顶点集U到V-U的代价最小的边的辅助数组定义
typedef struct
{
    VertexType adjvex;
    VRType lowcost;
} mid,minside[MAX_VERTEX_NUM];

int LocateVex(MGraph G, VertexType u)
{
    //初始条件:图G存在,u和G中顶点有相同特征
    //操作结构:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
    int i;
    for(i = 0; i < G.vexnum; i++)
    {
        //if(strcmp(u,G.vexs[i]) == 0)
        if(u == G.vexs[i])
            return i;
    }
    return -1;
}

//求SZ.lowcost的最小正值,并返回其在SZ中的序号
int minimum(minside SZ,MGraph G)
{
    int i = 0,j,k,min;
    while(!SZ[i].lowcost)
    {
        i++;
    }
    min = SZ[i].lowcost;
    k = i;
    for(j = i +  1; j < G.vexnum; j++)
    {
        if(SZ[j].lowcost > 0 && min > SZ[j].lowcost)
        {
            min = SZ[j].lowcost;
            k = j;
        }
    }
    return k;
}

void MiniSpanTree_PRIM(MGraph G,VertexType u)
{
    int i,j,k,ans = 0;
    minside closedge;
    k = LocateVex(G,u);
    for(j = 0; j < G.vexnum; ++j)
    {
        //strcpy(closedge[j].adjvex,u);
        closedge[j].adjvex = u;
        closedge[j].lowcost = G.arcs[k][j].adj;

    }
    closedge[k].lowcost = 0;
    //printf("最小生成树的各条边为
");
    int p,q;
    for(i = 1; i < G.vexnum; ++i)
    {
        k = minimum(closedge,G);
        //printf("(%d-%d)
",closedge[k].adjvex,G.vexs[k]);
        p = closedge[k].adjvex - 1;
        q = G.vexs[k] - 1;
        ans += G.arcs[p][q].adj;
        closedge[k].lowcost = 0;
        for(j = 0; j < G.vexnum; ++j)
        {
            if(G.arcs[k][j].adj < closedge[j].lowcost)
            {
                //strcpy(closedge[j].adjvex,G.vexs[k]);
                closedge[j].adjvex = G.vexs[k];
                closedge[j].lowcost = G.arcs[k][j].adj;
            }
        }
    }
    printf("%d
",ans);
}


//构建无向网,n个顶点,m条边
void CreateUDG(MGraph &G,int n,int m)
{
    int i,j,k,l;//IncInfo;
    char s[MAX_INFO];
    VertexType va,vb;
    //printf("请输入无向图G的顶点数,边数。
");
    //scanf("%d%d",&G.vexnum,&G.arcnum);
    
    G.vexnum = n;
    G.arcnum = m;

    //printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    
    for(i = 0; i < G.vexnum; i++)
    {
        G.vexs[i] = i + 1;
        //scanf("%s",G.vexs[i]);
    }
    for(i = 0; i < G.vexnum; i++)
    {
        for(j = 0; j < G.vexnum; j++)
        {
            G.arcs[i][j].adj = INF;
        }
    }
    //printf("请输入%d条边的顶点1,顶点2:
",G.arcnum);
    for(k = 0; k < G.arcnum; k++)
    {
        //printf("Case %d:",k + 1);
        scanf("%d %d %d",&va,&vb,&l);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        G.arcs[i][j].adj = G.arcs[j][i].adj = l;
    }
    G.kind = UDG;
}

int main()
{
    int n,m;
    MGraph G;
    while(scanf("%d%d",&n,&m) != EOF){
        CreateUDG(G,n,m); //创建无向图
        //Prt(G);
        MiniSpanTree_PRIM(G,G.vexs[0]);
    }
    return 0;
}
////储存结构:邻接矩阵
//功能:Dijkstra算法求最短路
enum GraphKind {DG,DN,UDG,UDN};

typedef int VRType;
//typedef char VertexType[12];
typedef int VertexType;

typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //路径矩阵
typedef int ShortPathTable[MAX_VERTEX_NUM]; //最短距离表

typedef struct
{
    VRType adj; //顶点关系类型。
    //InfoType *info; //该弧相关信息指针
} ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

struct MGraph
{
    VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
    AdjMatrix arcs; //邻接矩阵
    int vexnum,arcnum;//顶点数,弧数
    GraphKind kind;//图的种类标志
};

int LocateVex(MGraph G, VertexType u)
{
    //初始条件:图G存在,u和G中顶点有相同特征
    //操作结构:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
    int i;
    for(i = 0; i < G.vexnum; i++)
    {
        //if(strcmp(u,G.vexs[i]) == 0)
        if(u == G.vexs[i])
            return i;
    }
    return -1;
}

void ShortestPath_DIJ(MGraph G,int v0,PathMatrix P,ShortPathTable D)
{
    int v,w,i,j,min;
    int final[MAX_VERTEX_NUM];
    for(v = 0; v < G.vexnum; ++v){
        final[v] = FALSE;
        D[v] = G.arcs[v0][v].adj;
        for(w = 0; w < G.vexnum; ++w)
            P[v][w] = FALSE;
        if(D[v] < INF)
            P[v][v0] = P[v][v] = TRUE;
    }
    D[v0] = 0;
    final[v0] = TRUE;
    for(i = 1; i < G.vexnum; ++i){
        min = INF;
        for(w = 0; w < G.vexnum; ++w){
            if(!final[w] && D[w] < min){
                v = w;
                min = D[w];
            }
        }
        final[v] = TRUE;
        for(w = 0; w < G.vexnum; ++w){
            if(!final[w] && min < INF && G.arcs[v][w].adj < INF && (min + G.arcs[v][w].adj < D[w]))
            {
                D[w] = min + G.arcs[v][w].adj;
                for(j = 0; j < G.vexnum; ++j)
                    P[w][j] = P[v][j];
                P[w][w] = TRUE;
            }
        }
    }
}


//构建无向网,n个顶点,m条边
void CreateUDG(MGraph &G,int n,int m)
{
    int i,j,k,l;//IncInfo;
    char s[MAX_INFO];
    VertexType va,vb;
    //printf("请输入无向图G的顶点数,边数。
");
    //scanf("%d%d",&G.vexnum,&G.arcnum);
    
    G.vexnum = n;
    G.arcnum = m;

    //printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    
    for(i = 0; i < G.vexnum; i++)
    {
        G.vexs[i] = i + 1;
        //scanf("%s",G.vexs[i]);
    }
    for(i = 0; i < G.vexnum; i++)
    {
        for(j = 0; j < G.vexnum; j++)
        {
            G.arcs[i][j].adj = INF;
        }
    }
    //printf("请输入%d条边的顶点1,顶点2:
",G.arcnum);
    for(k = 0; k < G.arcnum; k++)
    {
        //printf("Case %d:",k + 1);
        scanf("%d %d %d",&va,&vb,&l);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        G.arcs[i][j].adj = G.arcs[j][i].adj = l;
    }
    G.kind = UDG;
}

int main()
{
    int n,m;
    MGraph G;
    PathMatrix p;
    ShortPathTable d;
    while(scanf("%d%d",&n,&m) != EOF){
        memset(p,0,sizeof(p));
        memset(d,0,sizeof(d));
        CreateUDG(G,n,m); //创建无向图
        ShortestPath_DIJ(G,0,p,d);
        printf("%d
",d[n - 1]);

    }
    return 0;
}
////存储方式:邻接表
//功能:拓扑排序,判断是否存在回路

//存储各顶点入度
int indegree[MAX_VERTEX_NUM];

enum GraphKind{DG,DN,UDG,UDN};

typedef char VertexType[12];

struct ArcNode
{
    int adjvex; //该弧所指向的顶点的位置
    ArcNode *nextarc; //指向下一条弧的指针
    //InfoType *info; //网的权值指针
};//表节点

typedef struct
{
    VertexType data; //顶点信息
    ArcNode *firstarc; //第一个表节点的地址,指向第一条依附该顶点的弧指针
}VNode,AdjList[MAX_VERTEX_NUM]; //头节点

struct ALGraph
{
    AdjList vertices;
    int vexnum,arcnum; //图的当点顶点数和弧数
    int kind; //图的种类标志
};

//返回u的顶点序号,若图中不含u,返回-1
int LocateVex(ALGraph G,VertexType u)
{
    int i;
    for(i = 0; i < G.vexnum; i++){
        if(strcmp(u,G.vertices[i].data) == 0)
            return i;
    }
    return -1;
}

void ListInsert(VNode &p,ArcNode e) //头插法
{
    ArcNode *q = (ArcNode *)malloc(sizeof(ArcNode));
    q->adjvex = e.adjvex;
    q->nextarc = p.firstarc;
    p.firstarc = q;

}

//创建有向图
void CreateDG(ALGraph &G){
    int i,j,k;
    VertexType va,vb;
    ArcNode e;
    printf("-----建立有向图-----
");
    printf("请输入图的顶点数,边数:");
    scanf("%d%d",&G.vexnum,&G.arcnum);
    printf("请输入%d个顶点的值(小于%d个字符):
",G.vexnum,MAX_NAME);
    for(i = 0; i < G.vexnum; i++){
        scanf("%s",G.vertices[i].data);
        G.vertices[i].firstarc = NULL;
    }
    printf("请输入每条弧的弧尾和弧头:
");
    for(k = 0; k < G.arcnum; k++){
        printf("Case %d:",k + 1);
        scanf("%s%s",va,vb);
        i = LocateVex(G,va);
        j = LocateVex(G,vb);
        //e.info = NULL; //图无权
        e.adjvex = j;
        ListInsert(G.vertices[i],e);
    }
    G.kind = DG;
}

//求图中各顶点入度,并存在indegree数组中
void FindInDegree(ALGraph G)
{
    int i;
    memset(indegree,0,sizeof(indegree));

    for(i = 0; i < G.vexnum; i++){
        ArcNode *p = G.vertices[i].firstarc;
        while(p){
            indegree[p->adjvex]++;
            p = p->nextarc;
        }
    }
}

//有向图G采用邻接表存储结构
//若G无回路,则输出G的顶点的拓扑序列并返回true,否则返回false
bool TopologicalSort(ALGraph G)
{
    int i,k;
    FindInDegree(G); //对各顶点求入度
    stack<int>s; //0入度顶点栈
    for(i = 0; i < G.vexnum; ++i){
        if(!indegree[i]) //入度为0
            s.push(i); 
    }
    ArcNode *p;
    int count = 0;//对输出顶点计数
    while(!s.empty()){
        i =s.top();
        s.pop();
        printf("%d %s
",i,G.vertices[i].data);
        count++;//输出i号顶点,并计数
        for(p = G.vertices[i].firstarc; p; p = p->nextarc){
            k = p->adjvex; //对i号顶点的每个邻接点的入度减1
            if(!(--indegree[k])) s.push(k); //若入度减为0,则入栈
        }
    }

    if(count < G.vexnum) 
        return false; //该图有回路
    else
        return true; //该图无回路
}
int main()
{
    ALGraph G;
    CreateDG(G);//创建有向图

    if(TopologicalSort(G))
        printf("无回路
");
    else
        printf("有回路
");
    return 0;
}
原文地址:https://www.cnblogs.com/chenyang920/p/5002506.html