zoukankan      html  css  js  c++  java
  • 向陈越姥姥哭诉----关键活动

    运行结果:

      1 /*
      2  * keyPath.c
      3  *
      4  *  Created on: 2017年5月17日
      5  *      Author: ygh
      6  */
      7 
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 
     11 #define MAX_VERTEX_NUM 100 /*define the max number of the vertex*/
     12 #define INFINITY 65535     /*define double byte no negitive integer max number is 65535*/
     13 #define ERROR -1
     14 
     15 typedef int vertex; /*define the data type of the vertex*/
     16 typedef int weightType; /*define the data type of the weight*/
     17 typedef char dataType; /*define the data type of the vertex value*/
     18 
     19 vertex inputOrder[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
     20 /*define the data structure of the Edge*/
     21 typedef struct eNode *ptrToENode;
     22 typedef struct eNode {
     23     vertex v1, v2; /*two vertex between the edge <v1,v2>*/
     24     weightType weight; /*the value of the edge's weight */
     25 };
     26 typedef ptrToENode edge;
     27 
     28 /*==================A adjacent link to describe a graph=========================================*/
     29 /*define the data structure adjacent table node*/
     30 typedef struct adjNode *ptrToAdjNode;
     31 typedef struct adjNode {
     32     vertex adjVerx; /*the index of the vertex*/
     33     weightType weight; /*the value of the weight*/
     34     ptrToAdjNode next; /*the point to point the next node*/
     35 };
     36 
     37 /*define the data structure of the adjacent head*/
     38 typedef struct vNode *ptrToVNode;
     39 typedef struct vNode {
     40     ptrToAdjNode head; /*the point to point the adjacent table node*/
     41     dataType data; /*the space to store the name of the vertex,but some time the vertex has no names*/
     42     weightType earliest; /*The earliest data of the project*/
     43     weightType latest; /*The latest time*/
     44 } adjList[MAX_VERTEX_NUM];
     45 
     46 /*define the data structure of graph*/
     47 typedef struct gLNode *ptrTogLNode;
     48 typedef struct gLNode {
     49     int vertex_number; /*the number of the vertex*/
     50     int edge_nunber; /*the number of the edge*/
     51     adjList g; /*adjacent table*/
     52 };
     53 typedef ptrTogLNode adjacentTableGraph; /*a graph show by adjacent table*/
     54 
     55 /*
     56  create a graph given the vertex number.
     57  @param vertexNum The verter number of the graph
     58  @return a graph with vertex but no any egdgs
     59  */
     60 adjacentTableGraph createLGraph(int vertexNum) {
     61     adjacentTableGraph graph;
     62 
     63     vertex v;
     64     graph = (adjacentTableGraph) malloc(sizeof(struct gLNode));
     65     graph->vertex_number = vertexNum;
     66     graph->edge_nunber = 0;
     67     /*initialize the adjacent table*/
     68     for (v = 0; v < graph->vertex_number; v++) {
     69         graph->g[v].head = NULL;
     70         graph->g[v].earliest = 0;
     71         graph->g[v].latest = INFINITY;
     72     }
     73     return graph;
     74 }
     75 
     76 /*
     77  insert a edge to graph.We will distinct oriented graph and undirected graph
     78  The e->v1 and e->v2 are the vertexs' indexs in the adjacent table
     79  @param graph The graph you want to insert edge
     80  @param e The edge you want to insert the graph
     81  @param isOriented Whether the graph is oriented graph.If the graph is oriented
     82  we will set adjacent table graph[v1]->head=v2 and set graph[v1].head=v2
     83  otherwise we only set graph[v1].head=v2
     84  */
     85 void insertEdgeToLink(adjacentTableGraph graph, edge e, int isOriented) {
     86     /*build node<v1,v2>*/
     87     ptrToAdjNode newNode;
     88     newNode = (ptrToAdjNode) malloc(sizeof(struct adjNode));
     89     newNode->adjVerx = e->v2;
     90     newNode->weight = e->weight;
     91     newNode->next = graph->g[e->v1].head;
     92     graph->g[e->v1].head = newNode;
     93     /*if the graph is directed graph*/
     94     if (!isOriented) {
     95         newNode = (ptrToAdjNode) malloc(sizeof(struct adjNode));
     96         newNode->adjVerx = e->v1;
     97         newNode->weight = e->weight;
     98         newNode->next = graph->g[e->v2].head;
     99         graph->g[e->v2].head = newNode;
    100     }
    101 }
    102 
    103 /*
    104  build a graph stored by adjacent table
    105  */
    106 adjacentTableGraph buildLGraph(int isOrdered) {
    107     adjacentTableGraph graph;
    108     edge e;
    109     vertex i;
    110     int vertex_num;
    111 
    112     scanf("%d", &vertex_num);
    113     graph = createLGraph(vertex_num);
    114     scanf("%d", &(graph->edge_nunber));
    115     if (graph->edge_nunber) {
    116         e = (edge) malloc(sizeof(struct eNode));
    117         for (i = 0; i < graph->edge_nunber; i++) {
    118             scanf("%d %d %d", &e->v1, &e->v2, &e->weight);
    119             e->v1--;
    120             e->v2--;
    121             insertEdgeToLink(graph, e, isOrdered);
    122         }
    123     }
    124 
    125     return graph;
    126 }
    127 
    128 /*==============================define a queue=====================================================*/
    129 /*define a list to store the element in the queue*/
    130 typedef vertex elementType;
    131 typedef struct node3 *pList;
    132 typedef struct node3 {
    133     elementType element;
    134     struct node3 *next;
    135 };
    136 
    137 /*define a queue to point the list*/
    138 typedef struct node4 *pQueue;
    139 typedef struct node4 {
    140     pList front; /*the front point to point the head of the list*/
    141     pList rear; /*the rear point to point the rear of of the list*/
    142 };
    143 
    144 /*create a empty list to store the queue element*/
    145 pList createEmptyList() {
    146     pList list;
    147     list = (pList) malloc(sizeof(struct node3));
    148     list->next = NULL;
    149     return list;
    150 }
    151 /*create a empty queye*/
    152 pQueue createEmptyQueue() {
    153     pQueue queue = (pQueue) malloc(sizeof(struct node4));
    154     queue->front = NULL;
    155     queue->rear = NULL;
    156     return queue;
    157 }
    158 
    159 /*
    160  Wether the queue is empty
    161  @param queue The queue need to adjust
    162  @return If the queue is null,return 1 otherwise return 0
    163  */
    164 int isQueueEmpty(pQueue queue) {
    165     return (queue->front == NULL);
    166 }
    167 
    168 /*
    169  Add a element to a queue,If the queue is null,we will create a new queue
    170  @parama queue The queue we will add elememt to
    171  @prama element The element we will add to queue
    172  */
    173 void addQueue(pQueue queue, elementType element) {
    174     if (isQueueEmpty(queue)) {
    175         pList list = createEmptyList();
    176         list->element = element;
    177         queue->front = queue->rear = list;
    178     } else {
    179         pList newNode = (pList) malloc(sizeof(struct node3));
    180         newNode->element = element;
    181         newNode->next = queue->rear->next;
    182         queue->rear->next = newNode;
    183         queue->rear = newNode;
    184     }
    185 }
    186 
    187 /*
    188  delete a element from a queue
    189  @param queue The queue will be deleted a element
    190  @return The element has been deleted
    191  */
    192 elementType deleteEleFromQueue(pQueue queue) {
    193     if (isQueueEmpty(queue)) {
    194         printf("the queue is empty,don't allow to delete elemet from it!");
    195         return -1;
    196     } else {
    197         pList oldNode = queue->front;
    198         elementType element = oldNode->element;
    199         if (queue->front == queue->rear) {
    200             queue->rear = queue->front = NULL;
    201         } else {
    202             queue->front = queue->front->next;
    203         }
    204         free(oldNode);
    205         return element;
    206     }
    207 }
    208 
    209 /*
    210  * We solve this problem by top sort,but we need to update the adjacent
    211  * vertex earliest value at decreasing the adjacent vertex in-degree,the
    212  * earliest the max value of parent's earliest value add the weight(last time).
    213  * The vertex which has no in-degree will set earliest to 0 at first time
    214  *
    215  * Top sort algorithms thoughts:
    216  * 1.we first initialize all vertex in-degree is zero,then we according to
    217  * the graph to set the each vertex in-degree.
    218  * 2.find zero in-degree vertex and put it in queue.
    219  * 3.get a vertex from a queue and record its index
    220  * 4.get the all adjacent vertex of the vertex and let them in-degree decrement,at this moment,if
    221  * some vertex has decrease into zero,we put them into queue.
    222  * 5.Execute this operation until the queue is empty
    223  *
    224  * @param grap A graph which use adjacent list is used to store the vertex
    225  * @param topOrder A <code>vertex</code> array to store the index of the
    226  *             vertex about the top queue
    227  * @return If the graph is no circle,indicate the top sort is correct 1 will be return
    228  * otherwise will return 0
    229  */
    230 int getEarliestDate(adjacentTableGraph graph, vertex topOrder[]) {
    231     vertex v;
    232     ptrToAdjNode w;
    233     int indegree[MAX_VERTEX_NUM], vertexConter = 0;
    234     /*
    235      * Create a queue to store the vertex whose in-degree is zero
    236      */
    237     pQueue queue = createEmptyQueue();
    238     /*
    239      * Initialize topOrder
    240      */
    241     for (v = 0; v < graph->vertex_number; v++) {
    242         indegree[v] = 0;
    243     }
    244     for (v = 0; v < graph->vertex_number; v++) {
    245         for (w = graph->g[v].head; w; w = w->next) {
    246             indegree[w->adjVerx]++;
    247         }
    248     }
    249 
    250     /*
    251      * Add in-degree vertex to queue
    252      */
    253     for (v = 0; v < graph->vertex_number; v++) {
    254         if (indegree[v] == 0) {
    255             addQueue(queue, v);
    256             graph->g[v].earliest = 0;
    257         }
    258     }
    259     while (!isQueueEmpty(queue)) {
    260         v = deleteEleFromQueue(queue);
    261         /*
    262          * Record the vertex of top sort
    263          */
    264         topOrder[vertexConter++] = v;
    265         for (w = graph->g[v].head; w; w = w->next) {
    266             if ((graph->g[v].earliest + w->weight)
    267                     > (graph->g[w->adjVerx].earliest)) {
    268                 graph->g[w->adjVerx].earliest = graph->g[v].earliest
    269                         + w->weight;
    270             }
    271             if (--indegree[w->adjVerx] == 0) {
    272                 addQueue(queue, w->adjVerx);
    273             }
    274         }
    275     }
    276 
    277     /*
    278      *Adjust whether all vertexes have been recorded
    279      */
    280     if (vertexConter == graph->vertex_number) {
    281         return 1;
    282     } else {
    283         return 0;
    284     }
    285 }
    286 
    287 /*
    288  * You know ,we need to let these vertex whose out-degree is zero
    289  * latest equal earliest.These whose out-degree is zero is the vertex which
    290  * the project's finish vertex
    291  * @param grap A graph which use adjacent list is used to store the vertex
    292  */
    293 void initLatest(adjacentTableGraph graph) {
    294     vertex v;
    295     ptrToAdjNode w;
    296     vertex outdegree[graph->vertex_number];
    297     for (v = 0; v < graph->vertex_number; v++) {
    298         outdegree[v] = 0;
    299     }
    300     for (v = 0; v < graph->vertex_number; v++) {
    301         for (w = graph->g[v].head; w; w = w->next) {
    302             outdegree[v]++;
    303         }
    304     }
    305     /*
    306      *find out-degree vertex and set them latest equal earliest
    307      */
    308     for (v = 0; v < graph->vertex_number; v++) {
    309         if (outdegree[v] == 0) {
    310             graph->g[v].latest = graph->g[v].earliest;
    311         }
    312     }
    313 }
    314 
    315 /*
    316  * Calculate the the latest by the earliest and the top sort result
    317  * From the class,we can know the latest value is minimal value amount the child vertex's latest
    318  * minus the weight(we use the weight as the lasting time).Before caller this method,we have
    319  * initialize the terminal vertex latest value.You can see the method above.
    320  *@param grap A graph which use adjacent list is used to store the vertex
    321  *@param topOrder a <code>vertex</code> array to store the top sort result
    322  *
    323  */
    324 void calculateTheLatest(adjacentTableGraph graph, vertex topOrder[]) {
    325     int length = graph->vertex_number, i;
    326     ptrToAdjNode w;
    327     vertex v;
    328     for (i = length - 1; i >= 0; i--) {
    329         for (v = 0; v < graph->vertex_number; v++) {
    330             for (w = graph->g[v].head; w; w = w->next) {
    331                 if (w->adjVerx == topOrder[i]) {
    332                     if (graph->g[v].latest
    333                             > (graph->g[topOrder[i]].latest - w->weight)) {
    334                         graph->g[v].latest = graph->g[topOrder[i]].latest
    335                                 - w->weight;
    336                     }
    337 
    338                 }
    339             }
    340         }
    341     }
    342 }
    343 
    344 /*
    345  * Print the key path,we know when child vertex's latest minus parent vertex's earliest
    346  * and minus the weight(we use the weight as the lasting time),if the result is  equal zero
    347  * indicating this is key path.we print them.
    348  *@param grap A graph which use adjacent list is used to store the vertex
    349  */
    350 void recordKeyActivity(adjacentTableGraph graph) {
    351     vertex v;
    352     ptrToAdjNode w;
    353     for (v = 0; v < graph->vertex_number; v++) {
    354         for (w = graph->g[v].head; w; w = w->next) {
    355             if (graph->g[w->adjVerx].latest - graph->g[v].earliest
    356                     == w->weight) {
    357                 printf("%d->%d
    ", v + 1, w->adjVerx + 1);
    358             }
    359         }
    360     }
    361 }
    362 
    363 /*
    364  * Get the earliest max value from all vertex.we search each vertex and find the max earliest
    365  * and return
    366  * @param grap A graph which use adjacent list is used to store the vertex
    367  */
    368 int getEarliestTime(adjacentTableGraph graph) {
    369     weightType maxTime = -1;
    370     vertex v;
    371     for (v = 0; v < graph->vertex_number; v++) {
    372         if (graph->g[v].earliest > maxTime) {
    373             maxTime = graph->g[v].earliest;
    374         }
    375     }
    376     return maxTime;
    377 }
    378 
    379 /*
    380  * Access graph vertex by the index of the vertex
    381  */
    382 void visit(adjacentTableGraph graph, vertex v) {
    383     printf("%d %d %d
    ", v, graph->g[v].earliest, graph->g[v].latest);
    384 }
    385 
    386 /*
    387  Depth first search a graph
    388  @param graph The graph need to search
    389  @param startPoint The fisrt point we start search the graph
    390  @paran int *visited The array we use to tag the vertex we has accessed.
    391  */
    392 void DFS(adjacentTableGraph graph, vertex startPoint, int *visited) {
    393     ptrToAdjNode p;
    394     visit(graph, startPoint);
    395     visited[startPoint] = 1;
    396     for (p = graph->g[startPoint].head; p; p = p->next) {
    397         if (visited[p->adjVerx] == 0) {
    398             DFS(graph, p->adjVerx, visited);
    399         }
    400     }
    401 }
    402 
    403 /*
    404  * Fill a array with value
    405  * @param arr The array need to be filled
    406  * @param length The length of the array
    407  * @param filledValue The value the array will be filled
    408  */
    409 void fullArray(int *arr, int length, int filledValue) {
    410     int i;
    411     for (i = 0; i < length; i++) {
    412         arr[i] = filledValue;
    413     }
    414 }
    415 
    416 int main() {
    417     adjacentTableGraph graph = buildLGraph(1);
    418     vertex topOrder[graph->vertex_number];
    419     vertex keyActivities[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    420     int bool = getEarliestDate(graph, topOrder);
    421     if (bool) {
    422         printf("%d
    ", getEarliestTime(graph));
    423     } else {
    424         printf("0
    ");
    425     }
    426     initLatest(graph);
    427     calculateTheLatest(graph, topOrder);
    428     recordKeyActivity(graph);
    429     return 0;
    430 }
  • 相关阅读:
    0713学期末了
    Oracle Redo日志的状态
    crontab调用shell访问sqlplus失败原因
    Solaris下批量杀进程
    oracle用户管理的完全恢复4:在ARCHIVELOG 模式(恢复打开的数据库)
    oracle用户管理的完全恢复3:在ARCHIVELOG 模式(恢复关闭的数据库)
    shell删除所有空行(忽略编码格式)
    oracle用户管理的完全恢复1:在NOARCHIVELOG 模式下执行恢复
    查看oracle用户权限
    OLTP与OLAP介绍
  • 原文地址:https://www.cnblogs.com/yghjava/p/6869182.html
Copyright © 2011-2022 走看看