zoukankan      html  css  js  c++  java
  • 数据结构学习第十八天

    14:07:40 2019-09-02 

    学习

    PTA第17题 六度空间理论

    可以在结构体中 加上一个属性来表示层数 

    我是利用一个整型变量 Level和 一个数组LevelSize来记录每层数量多少 

    需要注意要处理 最远距离小于6的情况

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 
      5 int NumberOfConnect[1001];
      6 typedef struct ENode* Edge;
      7 struct ENode
      8 {
      9     int V1, V2;
     10 };
     11 
     12 typedef struct Graph* MGraph;
     13 struct Graph
     14 {
     15     int Nv;
     16     int Ne;
     17     int G[1001][1001];
     18 };
     19 
     20 MGraph CreateMGraph(int MaxVertex)
     21 {
     22     MGraph Graph;
     23     Graph = (MGraph)malloc(sizeof(struct Graph));
     24     Graph->Nv = MaxVertex;
     25     Graph->Ne = 0;
     26     for (int i = 1; i <=Graph->Nv; i++)
     27         for (int j = 1; j <=Graph->Nv; j++)
     28             Graph->G[i][j] = 0;
     29     return Graph;
     30 }
     31 void Insert(MGraph Graph,Edge E)
     32 {
     33     Graph->G[E->V1][E->V2] = 1;
     34     Graph->G[E->V2][E->V1] = 1;
     35 }
     36 MGraph BuildGraph()
     37 {
     38     MGraph Graph;
     39     Edge E;
     40     int Nv;
     41     scanf("%d", &Nv);
     42     Graph = CreateMGraph(Nv);
     43     scanf("%d
    ", &(Graph->Ne));
     44     for (int i = 0; i < Graph->Ne; i++)
     45     {
     46         E = (Edge)malloc(sizeof(struct ENode));
     47         scanf("%d %d
    ", &(E->V1), &(E->V2));
     48         Insert(Graph, E);
     49     }
     50     return Graph;
     51 }
     52 
     53 int IsEdge(MGraph Graph,int V, int W)
     54 {
     55     return (Graph->G[V][W] == 1) ? 1 : 0;
     56 }
     57 
     58 //利用广度优先搜索
     59 #define Size 1001
     60 int Queue[Size];
     61 int Front = 1;
     62 int Rear = 0;
     63 int size = 0;
     64 int IsEmpty()
     65 {
     66     return (size == 0) ? 1 : 0;
     67 }
     68 int Succ(int Value)
     69 {
     70     if (Value < Size)
     71         return Value;
     72     else
     73         return 0;
     74 }
     75 void EnQueue(int V)
     76 {
     77     Rear = Succ(Rear + 1);
     78     Queue[Rear] = V;
     79     size++;
     80 }
     81 int DeQueue()
     82 {
     83     int V = Queue[Front];
     84     Front = Succ(Front + 1);
     85     size--;
     86     return V;
     87 }
     88 void InitializeQueue()
     89 {
     90     for (int i = 0; i < Size; i++)
     91         Queue[i] = 0;
     92     Front = 1;
     93     Rear = 0;
     94     size = 0;
     95 }
     96 int visited[1001];
     97 void InitializeVisited()
     98 {
     99     for (int i = 0; i < 1001; i++)
    100         visited[i] = 0;
    101 }
    102 int BFS(MGraph Graph, int V)
    103 {
    104     InitializeVisited();
    105     InitializeQueue();
    106     EnQueue(V);
    107     visited[V] = 1;
    108     int Level = 0;  //从第0层开始
    109     int LevelSize[1001] = {0};
    110     LevelSize[Level] = 1;    //第0层自己算一个元素
    111     NumberOfConnect[V]++;    //令该顶点可以访问的个数加1
    112     while (!IsEmpty())
    113     {
    114         int W = DeQueue();
    115         LevelSize[Level]--;
    116         for (int i = 1; i <= Graph->Nv; i++)
    117             if (!visited[i]&&IsEdge(Graph, W, i))
    118             {
    119                 LevelSize[Level+1]++;
    120                 EnQueue(i);
    121                 visited[i] = 1;
    122                 NumberOfConnect[V]++;
    123             }
    124         if (LevelSize[Level] == 0)
    125             Level++;
    126         if (Level==6)
    127             return NumberOfConnect[V];
    128     }
    129     //当 达不到6 层时
    130     return NumberOfConnect[V];
    131 }
    132 void OutPut(MGraph Graph,int V,float num)
    133 {
    134     printf("%d: %.2f%%
    ", V, (num / Graph->Nv) * 100);
    135 }
    136 void SDS(MGraph Graph)
    137 {
    138     for (int i = 1; i <= Graph->Nv; i++)
    139     {
    140         int num = BFS(Graph,i);
    141         OutPut(Graph,i,num);
    142     }
    143 }
    144 int main()
    145 {
    146     MGraph G;
    147     G = BuildGraph();
    148     SDS(G);
    149     return 0;
    150 }
    View Code

    在网络中,求两个不同顶点之间的所有路径中 边的权值之和最小的那一条路径

    这条路径就是两点之间的最短路径(Shortest Path)

    第一个顶点为起点(源点 Source)

    最后一个顶点为终点(Destination)

    问题分类:

    ①单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径

       Ⅰ.(有向/无向)无权图

       Ⅱ.(有向/无向)有权图

    ②多源最短路径问题:求任意两顶点间的最短路径

    无权图的单源最短路算法

      按照递增(非递减)的顺序找出到各个项点的最短路    //利用 广度优先遍历

    有权图的单源最短路算法

      按照递增(非递减)的顺序找出到各个项点的最短路    //利用 Dijkstra算法

    Dijkstra算法

      令$S=left{ ext源点s + 已经确定了最短路径的顶点 v_i ight}$

    多源最短路算法

    ①直接将单源最短路算法调用$V$遍     //对于稀疏图效果好

    ②Floyd算法    //对于稠密图效果好

    Floyd算法

    $D^k[i][j]=路径left{i ightarrow left{l leq k ight} ightarrow j ight}$ 的最小长度

    $D^0,D^1,cdots,D^{|V|-1}[i][j]  即给出了i到j的真正最短距离$

    三种算法:

      1 //无权图的单源最短路算法
      2 
      3 int Dist[50];   //S到W的最短距离(源点到某点的最短距离)
      4 int Path[50];  //S到W的路上经过的某顶点
      5 void InitializeDistAndPath()
      6 {
      7     for (int i = 0; i < 50; i++)
      8     {
      9         Dist[i] = -1;
     10         Path[i] = -1;
     11     }
     12 }
     13 void UnWeighted(MGraph Graph, Vertex S)
     14 {
     15     InitializeDistAndPath();
     16     EnQueue(S);
     17     Dist[S] = 0;
     18     while (!IsEmpty())
     19     {
     20         Vertex V = DeQueue();
     21         for (int W = 0; W < Graph->Nv; W++)
     22             if (Dist[W] == -1 && IsEdge(Graph, V, W))
     23             {
     24                 Dist[W] = Dist[V] + 1;
     25                 Path[W] = V;
     26                 EnQueue(W);
     27             }
     28     }
     29 }
     30 
     31 //有权图的单源最短路算法
     32 //Dijkstra算法   //不能解决有负边的情况
     33 int Dists[50];
     34 int Collected[50];
     35 int Paths[50];
     36 Vertex FindMinDist(MGraph Graph)   //返回未被收录顶点中 Dists最小者
     37 {
     38     Vertex MinV, V;
     39     int MinDist = INFINITY;
     40     for (V = 0; V < Graph->Nv; V++)
     41     {
     42         if (Collected[V]!=0&&Dists[V] < MinDist)
     43         {
     44             MinDist = Dists[V];
     45             MinV = V;
     46         }
     47     }
     48     if (MinDist < INFINITY)
     49         return MinV;
     50     else
     51         return 0;
     52 }
     53 int Dijkstra(MGraph Graph, Vertex S)
     54 {
     55     Vertex V;
     56     //初始化
     57     for (int i = 0; i < Graph->Nv; i++)
     58     {
     59         Dists[i] = Graph->G[S][i];   //计算出与源点直接相连的节点的Dists
     60         if (Dists[i] < INFINITY)
     61             Paths[i] = S; 
     62         else
     63             Paths[i] = -1;
     64     }
     65 
     66     Dists[S] = 0;  //将源点收入
     67     Collected[S] = 1;
     68 
     69     while (1)
     70     {
     71         V = FindMinDist(Graph);
     72         if (!V)
     73             break;
     74         Collected[V] = 1; //收录
     75         for (Vertex W = 0; W < Graph->Nv; W++)
     76         {
     77             if (Collected[W] == 0 && IsEdge(Graph, V, W))
     78             {
     79                 if (Graph->G[V][W] < 0) //有负边 
     80                     return -1; //不能解决
     81                 if (Dists[V] + Graph->G[V][W] < Dists[W])
     82                 {
     83                     Dists[W] = Dists[V] + Graph->G[V][W];
     84                     Paths[W] = V;
     85                 }
     86             }
     87         }
     88     }
     89     return 1; //算法执行完毕
     90 }
     91 
     92 //多源最短路算法
     93 //Floyd算法 
     94 int D[50][50];
     95 int Pa[50][50]; //计算最短路径
     96 int Floyd(MGraph Graph)
     97 {
     98     for (int i = 0; i < Graph->Nv; i++)
     99         for (int j = 0; j < Graph->Nv; j++)
    100         {
    101             D[i][j] = Graph->G[i][j];
    102             Pa[i][j] = -1;
    103         }
    104 
    105     for (int k = 0; k < Graph->Nv; k++)
    106         for (int i = 0; i < Graph->Nv; i++)
    107             for (int j = 0; j < Graph->Nv; j++)
    108                 if (D[i][k] + D[k][j] < D[i][j])
    109                 {
    110                     D[i][j] = D[i][k] + D[k][j];
    111                     if (i == j && D[i][j] < 0)
    112                         return -1;  //有负值圈 解决失败
    113                     Pa[i][j] = k;
    114                 }
    115 }
    View Code
  • 相关阅读:
    github
    mysql安装和应用
    11月9日(visio安装很坑)
    11月4日
    11月3日
    10月29日
    10月26日
    10月25日
    9月29日
    9月28日
  • 原文地址:https://www.cnblogs.com/57one/p/11446205.html
Copyright © 2011-2022 走看看