• 数据结构学习第二十天


    15:44:43 2019-09-04

    勉強します

    PTA第20题 Dijkstra算法的变形  其实是加了一个变量来辅助判别 那如果影响的判断的变量增加 就需要多加变量来 继续进行判断

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 #define INIFITY 65635
      5 int Departure;
      6 int Destination;
      7 typedef struct TypeInt Element;
      8 struct  TypeInt
      9 {
     10     int Length;
     11     int Price;
     12 };
     13 typedef struct ENode* Edge;
     14 struct ENode
     15 {
     16     int V1, V2;
     17     int Length;
     18     int Price;
     19 };
     20 
     21 typedef struct Graph* MGraph;
     22 struct Graph
     23 {
     24     int Nv;
     25     int Ne;
     26     Element G[500][500];
     27 };
     28 
     29 MGraph CreateGraph(int MaxVertex)
     30 {
     31     MGraph Graph = (MGraph)malloc(sizeof(struct Graph));
     32     Graph->Nv = MaxVertex;
     33     Graph->Ne = 0;
     34     for (int i = 0; i < Graph->Nv; i++)
     35         for (int j = 0; j < Graph->Nv; j++)
     36         {
     37                 Graph->G[i][j].Length= INIFITY;
     38                 Graph->G[i][j].Price = INIFITY;
     39         }
     40     return Graph;
     41 }
     42 
     43 void Insert(MGraph Graph, Edge E)
     44 {
     45     Graph->G[E->V1][E->V2].Length= E->Length;
     46     Graph->G[E->V2][E->V1].Length= E->Length;
     47     Graph->G[E->V1][E->V2].Price = E->Price;
     48     Graph->G[E->V2][E->V1].Price = E->Price;
     49 }
     50 
     51 MGraph BuildGraph()
     52 {
     53     MGraph Graph;
     54     Edge E;
     55     int Nv;
     56     scanf("%d", &Nv);
     57     Graph = CreateGraph(Nv);
     58     scanf("%d %d %d", &Graph->Ne,&Departure,&Destination);
     59     for (int i = 0; i < Graph->Ne; i++)
     60     {
     61         E = (Edge)malloc(sizeof(struct ENode));
     62         scanf("%d %d %d %d
    ", &(E->V1), &(E->V2), &(E->Length),&(E->Price));
     63         Insert(Graph, E);
     64     }
     65     return Graph;
     66 }
     67 
     68 int IsEdge(MGraph Graph, int V, int W)
     69 {
     70     return (Graph->G[V][W].Length < INIFITY) ? 1 : 0;
     71 }
     72 int Dist[500];        //从源点到某点的路径长度
     73 int Price[500];        //从源点到某点的价格
     74 int Path[500];        //记录路径
     75 int Collected[500]; //记录是否收录
     76 int FindMinDist(MGraph Graph)
     77 {
     78     int MinDist = INIFITY;
     79     int V;
     80     for (int i = 0; i < Graph->Nv; i++)
     81     {
     82         if (!Collected[i]&&Dist[i] < MinDist)
     83         {
     84             MinDist = Dist[i];
     85             V = i;
     86         }
     87     }
     88     if (MinDist < INIFITY)
     89         return V;
     90     else
     91         return 0;
     92 }
     93 void Dijkstra(MGraph Graph,int S)
     94 {
     95     //先初始化源点连接的点
     96     for (int i = 0; i < Graph->Nv; i++)
     97     {
     98         Dist[i] = Graph->G[S][i].Length;
     99         Price[i] = Graph->G[S][i].Price;
    100         if (IsEdge(Graph,S,i))
    101             Path[i] = S;
    102         else
    103             Path[i] = -1;
    104     }
    105 
    106     Collected[S] = 1;
    107     Dist[S] = 0;
    108     Price[S] = 0;
    109 
    110     while (1)
    111     {
    112         int V = FindMinDist(Graph);
    113         if (!V)
    114             break;
    115         Collected[V] = 1;
    116         for (int i = 0; i < Graph->Nv; i++)
    117         {
    118             if (!Collected[i] && IsEdge(Graph, V, i))
    119             {
    120                 if (Dist[V] + Graph->G[V][i].Length < Dist[i])
    121                 {
    122                     Dist[i] = Dist[V] + Graph->G[V][i].Length;
    123                     Path[i] = V;
    124                     Price[i] = Price[V] + Graph->G[V][i].Price;
    125                 }
    126                 else if (Dist[V] + Graph->G[V][i].Length == Dist[i]) 
    127                 {
    128                     if (Price[V] + Graph->G[V][i].Price < Price[i])
    129                     {
    130                         Price[i] = Price[V] + Graph->G[V][i].Price;
    131                         Path[i] = V;
    132                     }
    133                 }
    134             }
    135                 
    136         }
    137     }
    138 }
    139 int main()
    140 {
    141     MGraph Graph = BuildGraph();
    142     Dijkstra(Graph,Departure);
    143     printf("%d %d", Dist[Destination], Price[Destination]);
    144     return 0;
    145 }
    View Code

     

    最小生成树(Minimum Spanning Tree)

    利用贪心算法

    什么是"贪":每一步都要最好的

     两种有名的贪心算法

    ①Prim算法------让一颗小树长大

    ②Kruskal算法------将森林合并成树

    Prim算法  //稠密图合算

    Kruskal算法

      1 #define _CRT_SECURE_NO_WARNINGS  
      2 #include<stdio.h>
      3 #include<malloc.h>
      4 
      5 //图的邻接矩阵表示法
      6 #define MaxVerterNum 100    //最大顶点数
      7 #define INFINITY 65535        //
      8 typedef int Vertex;            //顶点下标表示顶点
      9 typedef int WeightType;        //边的权值
     10 typedef char DataType;        //顶点存储的数据类型
     11 
     12 //边的定义
     13 typedef struct ENode* PtrToENode;
     14 typedef PtrToENode Edge;
     15 struct ENode
     16 {
     17     Vertex V1, V2; //有向边<V1,V2>
     18     WeightType Weight;  //权重
     19 };
     20 
     21 //图节点的定义
     22 typedef struct GNode* PtrToGNode;
     23 typedef PtrToGNode MGraph;   //以邻接矩阵存储的图类型
     24 struct GNode
     25 {
     26     int Nv;    //顶点数
     27     int Ne;    //边数
     28     WeightType G[MaxVerterNum][MaxVerterNum];   //邻接矩阵
     29     DataType Data[MaxVerterNum];            //存顶点的数据
     30 };
     31 
     32 MGraph CreateGraph(int VertexNum)
     33 {//初始化一个有VerterNum个顶点但没有边的图
     34     Vertex V, W;
     35     MGraph Graph;
     36 
     37     Graph = (MGraph)malloc(sizeof(struct GNode));  //建立图
     38     Graph->Nv = VertexNum;
     39     Graph->Ne = 0;
     40     //初始化邻接矩阵
     41     for (V = 0; V < Graph->Nv; V++)
     42         for (W = 0; W < Graph->Nv; W++)
     43             Graph->G[V][W] = INFINITY;
     44     return Graph;
     45 }
     46 
     47 void InsertEdge(MGraph Graph, Edge E)
     48 {
     49     //插入边<V1,V2>
     50     Graph->G[E->V1][E->V2] = E->Weight;
     51     //如果是无向图 还要插入边<V2,V1>
     52     Graph->G[E->V2][E->V1] = E->Weight;
     53 }
     54 
     55 MGraph BuildGraph()
     56 {
     57     MGraph Graph;
     58     Edge E;
     59     Vertex V;
     60     int Nv, i;
     61 
     62     scanf("%d", &Nv);  //读入顶点个数
     63     Graph = CreateGraph(Nv);  //初始化有Nv个顶点但没有边的图
     64 
     65     scanf("%d", &(Graph->Ne));  //读入边数
     66     if (Graph->Ne != 0)        //如果有边
     67     {
     68         E = (Edge)malloc(sizeof(struct  ENode));  //建立边节点
     69         //读入边 格式为 起点 终点 权重 插入邻接矩阵
     70         for (int i = 0; i < Graph->Ne; i++)
     71         {
     72             scanf("%d %d %d", &(E->V1), &(E->V2), &(E->Weight));
     73             InsertEdge(Graph, E);
     74         }
     75     }
     76     //若顶点有数据 读入数据
     77     for (V = 0; V < Graph->Nv; V++)
     78         scanf("%c", &(Graph->Data[V]));
     79     return Graph;
     80 }
     81 
     82 int IsEdge(MGraph Graph, int V, int W)
     83 {
     84     return (Graph->G[V][W] < INFINITY) ? 1 : 0;
     85 }
     86 //邻接矩阵存储 Prim最小生成树的算法
     87 int Dist[50];  //表示某个点到树的距离
     88 int Parent[50];   //利用双亲表示法 :儿子指向父亲
     89 Vertex    FindMinDist(MGraph Graph)   //返回未被收录顶点中 dist为最小的顶点
     90 {
     91     int MinDist = INFINITY;
     92     int V;
     93     for (int i = 0; i < Graph->Nv; i++)
     94     {
     95         if (!Dist[i] && Dist[i] < MinDist)
     96         {
     97             MinDist = Dist[i];
     98             V = i;
     99         }
    100     }
    101     if (MinDist < INFINITY)
    102         return V;
    103     else
    104         return 0;   //返回0做为 找不到顶点的标记
    105 }
    106 
    107 int Prim(MGraph Graph,Vertex S)    //从S开始  返回顶点数
    108 {
    109     int Vcount=0;        //收录的顶点数 
    110     for (int i = 0; i < Graph->Nv; i++)    //初始化
    111     {
    112         Dist[i] = Graph->G[S][i];
    113         if (Dist[i] < INFINITY)
    114             Parent[i] = S;
    115         else
    116             Parent[i] = -1;
    117     }
    118     Dist[S] = 0;  //将S收录
    119     Vcount++;
    120     while (1)
    121     {
    122         int V = FindMinDist(Graph);
    123         if (!V)
    124             break;
    125         Dist[V] = 0;   //将V收录
    126         Vcount++;
    127         for (int i = 0; i < Graph->Nv; i++)
    128         {
    129             if (!Dist[i] &&IsEdge(Graph,V,i))
    130             {
    131                 if(Graph->G[V][i]<Dist[i])
    132                     Dist[i] = Graph->G[V][i];
    133                     Parent[i] = V;
    134             }
    135         }
    136     }
    137     if (Vcount < Graph->Nv)
    138         return 0;    //收到的顶点不到Nv个  失败 无法成为最小生成树
    139     else
    140         return Vcount;
    141 }
    View Code

    写在最后: 到这基本认识了 树 与 图 (Kruskai算法还没实现) 暑假也到最后一天了 希望自己以后变得越来越好

  • 相关阅读:
    java SE :文件基本处理 File、FileFilter、FileNameFilter
    java SE :标准输入/输出
    java EE :GenericServlet 抽象类、ServletConfig 接口
    java EE :Servlet 接口
    java EE : http 协议响应头部信息验证
    java EE : http 协议之请求报文、响应报文
    java EE : tomacat 基础
    06 java 基础:java 循环 递归
    05 java 基础:运算符、程序结构
    04 java 基础:数据类型
  • 原文地址:https://www.cnblogs.com/57one/p/11459580.html
Copyright © 2020-2023  润新知