华为codecraft算法大赛---寻路

来源:互联网 发布:立秋网络怎么获得学时 编辑:程序博客网 时间:2024/05/16 01:04

华为codecraft算法大赛—寻路

前言

最近实验室的师兄师姐们在热火朝天的笔试(都说难难难),我也要了些题来感受了一下,已然被虐的体无完肤。选择题考的内容涉及范围广,算法编程题对于没有刷题经验的我来说就更是难上加难了。看来有必要在学习工作之余学习学习算法以及计算机基础知识了。

翻了上半年参加华为codecraft算法大赛的代码,趁周末整理一下当时的思路以及回顾一下数据结构与算法。比赛前中期还保持不错的名次,一直维持在二十名左右以为稳稳三十二强了,结果后期突破不大,最后几天呼呼的被超过,真是太天真了。后来回想确实方法思路比较死板,一口咬定DFS+剪枝,没有去尝试新的算法如A*,模拟退火算法等,还有大赛群里分享说的动态规划、数模等。

比赛源码以及样例数据在我的github:
https://github.com/hczheng/2016Codecraft

赛题介绍

1 问题定义
给定一个带权重的有向图G=(V,E),V为顶点集,E为有向边集,每一条有向边均有一个权重。对于给定的顶点s、t,以及V的子集V’,寻找从s到t的不成环有向路径P,使得P经过V’中所有的顶点(对经过V’中节点的顺序不做要求)。
若不存在这样的有向路径P,则输出无解,程序运行时间越短,则视为结果越优;若存在这样的有向路径P,则输出所得到的路径,路径的权重越小,则视为结果越优,在输出路径权重一样的前提下,程序运行时间越短,则视为结果越优。
说明:
1)图中所有权重均为[1,20]内的整数;
2)任一有向边的起点不等于终点;
3)连接顶点A至顶点B的有向边可能超过一条,其权重可能一样,也可能不一样;
4)该有向图的顶点不会超过600个,每个顶点出度(以该点为起点的有向边的数量)不超过8;
5)V’中元素个数不超过50;
6)从s到t的不成环有向路径P是指,P为由一系列有向边组成的从s至t的有向连通路径,且不允许重复经过任一节点;
7)路径的权重是指所有组成该路径的所有有向边的权重之和。

2 输入与输出
输入文件格式
以两个.csv 文件(csv 是以逗号为分隔符的文本文件)给出输入数据,一个为图的数据(G),一个为需要计算的路径信息(s,t,V’)。文件每行以换行符(ASCII’\n’即0x0a)为结尾。

1)图的数据中,每一行包含如下的信息:
LinkID,SourceID,DestinationID,Cost
其中,LinkID 为该有向边的索引,SourceID 为该有向边的起始顶点的索引,DestinationID为该有向边的终止顶点的索引,Cost 为该有向边的权重。顶点与有向边的索引均从0 开始 编号(不一定连续,但用例保证索引不重复)。
2)路径信息中,只有一行如下数据:
SourceID,DestinationID,IncludingSet
其中,SourceID 为该路径的起点,DestinationID 为该路径的终点,IncludingSet 表示必须经过的顶点集合V’,其中不同的顶点索引之间用’|’分割。
输出文件格式
输出文件同样为一个.csv 文件。
1)如果该测试用例存在满足要求的有向路径P,则按P 经过的有向边顺序,依次输出有向边的索引,索引之间用’|’分割;
2)如果该测试用例不存在满足要求的有向路径P,则输出两个字符NA;
3)只允许输出最多一条有向路径。

3.简单用例说明

赛题思路

我当时第一反应就是最短路径算法,但是直接套用过来是肯定不行的,因为最短路径算法(dijkstra)是一层一层往外扩,然后利用贪心算法的思想得到每一层级的最优路径。二本赛题加了必过点的限制,因此需要对算法进行改造,为了能得到赛题结果,在一步步改造的过程中发现已经抛弃了贪心算法思想,最后渐渐的升级深度优先遍历(DFS)的基本思想,但是记录每一步遍历的顺序,方便回溯(在找到可行解的基础上还要考虑最优解)。随着比赛的进行,赛题数据复杂度的增加,回溯版DFS不能在有效的时间内得到最优解,甚至不能得到一个可行解。因此我又在该基础上增加了”剪枝”的思想,就是剪断一些出度较大的节点的路径,这样可以降低复杂度,并且能得到不错的结果,“剪枝”的尺度与位置其实是随机(缺乏科学性)的,由于是比赛,所以可以通过评分程序去修改算法拟合赛题数据。也是因为这种小聪明导致我这次比赛前中期效果不错,后期却非常乏力。这是应该吸取的教训,还是应该从算法本身的有效性入手,那样才会有真正的提高。

以下是输入数据以及输出结果样例



比赛源码

比赛要求的编译环境是Linux+gcc;为了方便调试,以下代码(已带详细注释)是Windows+Visual Stdio下的,有兴趣可以自行转换,也可以在以下地址下载提交版(包括华为官方提供的编译脚本)。

#include "stdafx.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <fstream> using namespace std;#define PRINT  printf#define MAX_RECORD  100#define MAX_LINE_LEN 4000#define Error( Str )   FatalError( Str )#define FatalError( Str )   fprintf( stderr, "%s\n", Str ), exit( 1 )//邻接表读图,//前面这些把图读进邻接表,typedef struct ListNode *Position;//位置typedef Position List;//链表typedef struct Tbl *Table;//邻接表typedef int ElementType;typedef int Vertex;//顶点typedef struct VertexTable *VerTable;//例子4个顶点#define Infinity 65536 //各个顶点初始化#define NotAVertex -1#define nowstart 0//当前起点,初始化为0#define NotFound -1//折半查找#define LeftChild(i) (2*(i)+1)//堆排序                         typedef struct StackRecord *Stack;#define EmptyTOS -1//*************************************读文件********************************************//int read_file(char ** const buff, const unsigned int spec, const char * const filename){    FILE *fp = fopen(filename, "r");    if (fp == NULL)    {        PRINT("Fail to open file %s, %s.\n", filename, strerror(errno));        return 0;    }    PRINT("Open file %s OK.\n", filename);    char line[MAX_LINE_LEN + 2];    unsigned int cnt = 0;    while ((cnt < spec) && !feof(fp))    {        line[0] = 0;        fgets(line, MAX_LINE_LEN + 2, fp);        if (line[0] == 0)   continue;        buff[cnt] = (char *)malloc(MAX_LINE_LEN + 2);        strncpy(buff[cnt], line, MAX_LINE_LEN + 2 - 1);        buff[cnt][4001] = 0;        cnt++;    }    fclose(fp);    PRINT("There are %d lines in file %s.\n", cnt, filename);    return cnt;}//*************************************基本数据结构********************************************//struct StackRecord{    int Capacity;    int TopOfStack;    ElementType *Array;};////创建栈Stack CreateStack(int MaxElements){    Stack S;    S = (struct StackRecord*)malloc(sizeof(struct StackRecord));    if (S == NULL)        FatalError("Out of space!!!");    S->Array = (int*)malloc(sizeof(ElementType)*MaxElements);    if (S->Array == NULL)        FatalError("Out of space!!!");    S->Capacity = MaxElements;    S->TopOfStack = EmptyTOS;    return S;}//出栈void Pop(Stack S){    if (S->TopOfStack == EmptyTOS)        Error("Empty Stack");    else        S->TopOfStack--;}//入栈void Push(ElementType X, Stack S){    if (S->TopOfStack == S->Capacity - 1)        Error("Full stack");    else        S->Array[++S->TopOfStack] = X;}//销毁栈void DisposeStack(Stack S){    if (S != NULL)    {        free(S->Array);        free(S);    }}ElementType Top(Stack S){    if (S->TopOfStack != EmptyTOS)    {        return S->Array[S->TopOfStack];    }    else    {        Error("Empty Stack");        return 0;    }}//链表,每个存储了顶点Element,权重Cost,指向下一个的Next;struct ListNode{    ElementType ELement;    int Cost;    int Priority;    int Edge;    Position Next;};//0->1,1   Element=1,cost=1;  //邻接表struct Tbl{    int TableSize;    List *TheLists;};//顶点表struct VertexTable{    int known;    int Dist;    Vertex Path;};//*************************************邻接表初始化******************************************//Table InitializeTable(int TableSize){    Table T;    int i;    T = (struct Tbl*)malloc(sizeof(struct Tbl));    if (T == NULL)        FatalError("Out of space!!!");    T->TableSize = TableSize;    T->TheLists = (struct ListNode**)malloc(sizeof(List)*T->TableSize);    for (i = 0;i<T->TableSize;i++)    {        T->TheLists[i] = (struct ListNode*)malloc(sizeof(struct ListNode));        if (T->TheLists[i] == NULL)            FatalError("Out of space!!!");        else            T->TheLists[i]->Next = NULL;    }    return T;}//*************************************链表插入********************************************//void Insert(int Edge, ElementType Pos, ElementType Key, ElementType Cost, ElementType Priority, Table T){    Position NewCell;    List L;    NewCell = (struct ListNode*)malloc(sizeof(struct ListNode));    if (NewCell == NULL)        FatalError("Out of space!!!");    else    {        L = T->TheLists[Pos];        NewCell->Next = L->Next;        NewCell->Edge = Edge;        NewCell->ELement = Key;        NewCell->Cost = Cost;        NewCell->Priority = Priority;        L->Next = NewCell;    }}//*************************************顶点表初始化*****************************************//VerTable InitialWeighted(Vertex Start, VerTable V, int NumVertex)//V为顶点集合,每隔顶点有三种标记{    int i;    V = (struct VertexTable*)malloc(sizeof(struct VertexTable)*NumVertex);    for (i = 0;i<NumVertex;i++)    {        V[i].known = 0;        V[i].Dist = 0;        V[i].Path = NotAVertex;    }    V[Start].Dist = 0;    return V;}//*************************************二分查找********************************************//int BinarySearch(const ElementType A[], ElementType X, int N){    int Low, Mid, High;    Low = 0;High = N - 1;    while (Low <= High)    {        Mid = (Low + High) / 2;        if (A[Mid]<X)            Low = Mid + 1;        else            if (A[Mid]>X)                High = Mid - 1;            else                return Mid;    }    return NotFound;}void MakeEmpty(List L){    Position P, Tmp;    P = L->Next;    L->Next = NULL;    while (P != NULL)    {        Tmp = P->Next;        free(P);        P = Tmp;    }}void Disposable(Table T){    int i;    for (i = 0;i<T->TableSize;i++)    {        MakeEmpty(T->TheLists[i]);    }    free(T->TheLists);    free(T);}//*************************************堆排序********************************************//void PercDown(ElementType A[], int i, int N){    int Child;    ElementType Tmp;    for (Tmp = A[i];LeftChild(i)<N;i = Child)    {        Child = LeftChild(i);        if (Child != N - 1 && A[Child + 1]>A[Child])            Child++;        if (Tmp<A[Child])            A[i] = A[Child];        else            break;    }    A[i] = Tmp;}void Swap(int *a, int *b){    int temp;    temp = *a;    *a = *b;    *b = temp;}void Heapsort(ElementType A[], int N){    int i;    for (i = N / 2;i >= 0;i--)        PercDown(A, i, N);    for (i = N - 1;i>0;i--)    {        Swap(&A[0], &A[i]);        PercDown(A, 0, i);    }}//*************************************打印路径********************************************//void PrintPath(Vertex Ver, VerTable V, int C[]){    if (V[Ver].Path != NotAVertex)    {        PrintPath(V[Ver].Path, V, C);        printf("->");    }    printf("%d", C[Ver]);}//************************************输出边编号*******************************************//int find_route(int stop, Table T, VerTable V){    Position Tmp;    int result = -1;    Tmp = T->TheLists[V[stop].Path]->Next;//    while (Tmp != NULL)    {        if (Tmp->ELement == stop) { result = Tmp->Edge;break; }        Tmp = Tmp->Next;    }    return result;}///*************************************重复边处理****************************************//Position FindPrevious(ElementType X, List L){    Position P;    P = L;    while (P->Next != NULL && P->Next->ELement != X)        P = P->Next;    return P;}int IsLast(Position P, List L){    return P->Next == NULL;}void Delete(ElementType X, List L){    Position P, TmpCell;    P = FindPrevious(X, L);    if (!IsLast(P, L))  /* Assumption of header use */    {                      /* X is found; delete it */        TmpCell = P->Next;        P->Next = TmpCell->Next;  /* Bypass deleted cell */        free(TmpCell);    }}Position Find(ElementType X, List L){    Position P;          P = L->Next;          while (P != NULL && P->ELement != X)           P = P->Next;          return P;}///*******************************/自定义查找下一顶点的算法*************************************//int find_start(VerTable V, Table T, ElementType demand[], int start_now, int known_p, int end, Stack S, int N){    //传入的参数分别为:顶点表(konwn,dis,path)、优先点集、当前遍历起点    //返回值为下一个起点索引TempV,以及特征点入栈    Position tmp;    int min = Infinity;//普通点最小权值    int min_sp = Infinity;//优先点最小权值    int count_sp = 0;//优先点计数(用于判断特征点)    int count_normal = 0;//普通点计数    int normal[8] = { 0 };//普通点数组(暂存)    int special[8] = { 0 };//优先点数组(暂存)    Vertex TempV = -1;//开始标记    int flag = 0;//终点标记                 //TMP = T->TheLists[start_now];    tmp = T->TheLists[start_now]->Next;    while (tmp != NULL) //0->3->1->NULL  还有邻接点且未到达过    {        if (V[tmp->ELement].known != 1) {            if (tmp->Priority == 1)//如果该顶点是优先点            {                count_sp++;//当前层级优先点数+1                if (tmp->Cost < min_sp) //当前点权值更小                {                    if (count_sp > 1)                    {                        special[count_sp - 2] = TempV;                        V[TempV].Dist = 0;                    }                    min_sp = tmp->Cost;//更新min_sp                                       TempV = tmp->ELement;//返回值                    V[TempV].Dist = V[start_now].Dist + tmp->Cost;                }                else                {                    if (count_sp > 1)                    {                        special[count_sp - 2] = tmp->ELement;;                    }                }            }            else if (tmp->ELement == end)//如果该顶点是终点            {                flag = 1;//表明这一轮有终点,但暂时不作处理                V[end].Dist = V[start_now].Dist + tmp->Cost;                V[end].Path = start_now;            }            else //如果该顶点是普通点            {                count_normal++;//普通点计数                normal[count_normal - 1] = tmp->ELement;//普通点暂存                if (count_sp == 0 && tmp->Cost < min)//(1.有普通点没有终点没有优先点2.有普通点有终点没有优先点)                {                    min = tmp->Cost;//更新min                    V[TempV].Dist = 0;                    TempV = tmp->ELement;//返回值                      V[TempV].Dist = V[start_now].Dist + tmp->Cost;                }            }        }        tmp = tmp->Next;    }    ///////////*************************LOOK***************************///////////////    if (count_sp == 0) //假如没有优先点,则把多余的普通点全部入栈    {        for (int i = 0;i < count_normal;i++)        {            if (TempV != normal[i])            {                Push(normal[i], S);Push(start_now, S);//V[normal[i]].Path = start_now;            }        }//普通点分支入栈          }    else//当优先点数>=1时    {        if (count_sp == 1)//假如刚好只有一个优先点,那么普通点入栈,并赋值path        {            for (int i = 0;i < count_normal;i++) { Push(normal[i], S); Push(start_now, S); }//V[normal[i]].Path = start_now;        }        else//当优先点数大于1时,普通点先全部入栈,然后多余的优先点入栈        {            for (int i = 0;i < count_normal;i++) { Push(normal[i], S); Push(start_now, S); } //V[normal[i]].Path = start_now;            for (int i = 0;i < count_sp - 1;i++) { Push(special[i], S);Push(start_now, S); }//V[special[i]].Path = start_now;        }    }    if (flag == 1 && known_p == N)//已到终点,且这一层没有优先点了,就要判断是否已经结束(优先点已全部在路径中)    {        TempV = 10000; //10000结束标志,到达终点且所有的优先点已在路径中    }    if (TempV == -1) { TempV = -start_now; if (start_now == 0) { TempV = -1000; } }//返回停止点(带负号,方便处理)    if (TempV != 10000 && TempV >= 0) { V[TempV].Path = start_now; }    return TempV;//返回下一起点索引}//**************************************核心查找算法********************************************//int DF(VerTable V, Table T, ElementType demand[], Stack S, int N, int start_now, int end, unsigned short *result,int big){    //Vertex Ver, W;//顶点索引    Position Tmp;    //int end = 5;//假定一个终点    int startone=start_now ;//存起点    int known_p = 0;//记录已到过的优先点    int flag = 0;//遍历过优先点标记    int min_dist = 10000;    int ok = 0;    for (;;)    {        if (start_now == 10000)//当前起点为10000,查找成功        {            flag++;//迭代次数            if (min_dist > V[end].Dist)            {                int tmp = end;                int count = 0;                while (tmp != startone)                {                   result[count] = find_route(tmp, T, V);                   count++;                   ok = count;                   tmp = V[tmp].Path;                }                min_dist = V[end].Dist;            }            else V[end].Dist = min_dist;             if (S->TopOfStack == -1||flag>10) break;                printf("flag:%d\n",flag);                           //if (big>7&&big<30)break;                //if (big>150 && big<200&&flag>7)break;                //if (big>200 && big<250 && flag>3)break;                if (big>250&&flag>0)break;                int pass = Top(S);//获得特征点索引 0->1->3                                 Pop(S);//出栈                start_now = Top(S);//将当前起点改为栈顶元素                        int stop = V[end].Path;//继续回溯                while (stop != pass)                {                    V[stop].known = 0;                    if (BinarySearch(demand, stop, N) >= 0) { known_p--; }                    stop = V[stop].Path;                }                Pop(S);//出栈                 /*if (S->TopOfStack != -1) {                    if (big> 150&&big<200) { Pop(S);Pop(S); }//边数在                    if (big> 200 && big<250) { Pop(S);Pop(S);Pop(S);Pop(S); }//边数在200-250,一次剪断两条边                    if (big> 250) { Pop(S);Pop(S);Pop(S);Pop(S);Pop(S);Pop(S); }//边数大于250,一次剪断三条边*/                //剪枝操作                V[start_now].Path = pass;//出栈起点路径信息                Tmp = T->TheLists[pass]->Next;                while (Tmp != NULL)                {                    if (Tmp->ELement == start_now) { V[start_now].Dist = V[pass].Dist + Tmp->Cost; }                    Tmp = Tmp->Next;                }        }               if (start_now < 0 && S->TopOfStack == -1) break; //栈空,则返回无解        if (start_now <0)//回头        {            int stop = -start_now;//停止点            if (start_now == -1000) { stop = 0; }//0为停止点的情况            int pass = Top(S);//获得特征点索引 0->1->3                             Pop(S);//出栈            //printf("%d出栈:\n", pass);            start_now = Top(S);//将当前起点改为栈顶元素                        while (stop != pass)            {                V[stop].known = 0;                if (BinarySearch(demand, stop, N) >= 0) { known_p--; }                //printf("%d回撤:\n", stop);                stop = V[stop].Path;                //V[stop].Path = NotAVertex;            }            Pop(S);//出栈             //printf("%d出栈:\n", start_now);            if (S->TopOfStack != -1) {                //if (big>150 && big < 200) { Pop(S);Pop(S);}//边数在150-200之间,一次剪断一条边                if (big> 100&&big<250) { Pop(S);Pop(S);Pop(S);Pop(S); }//边数在200-250,一次剪断两条边                if (big> 250) { Pop(S);Pop(S);Pop(S);Pop(S);Pop(S);Pop(S);}//边数大于250,一次剪断三条边            }//剪枝操作            V[start_now].Path = pass;//出栈起点路径信息            Tmp = T->TheLists[pass]->Next;            while (Tmp != NULL)            {                if (Tmp->ELement == start_now) { V[start_now].Dist = V[pass].Dist + Tmp->Cost; }                Tmp = Tmp->Next;            }        }        V[start_now].known = 1;//将当前起点标记为已知        if (BinarySearch(demand, start_now, N) >= 0) { known_p++; }//记录到达的优先点数        start_now = find_start(V, T, demand, start_now, known_p, end, S, N);//按自定义方法找下一个起点        printf("当前点:%d\n",start_now);    }    return ok;}//**************************************调用算法********************************************//void search_route(char *graph[5000], int edge_num, char *condition)//字符串数组(topo),行数,字符串(demand){    Table T = InitializeTable(600);//顶点    VerTable V = NULL;    Stack S = CreateStack(1000);//创建栈(存分支点)    unsigned short result[100] = { -1 };//示例中的一个解     const int n = edge_num;    int  N, start_now, end, demand[100] = { -1 }, test[400][4] = { 0 };    char *save_ptr, *line;//存剩余的    for (int i = 0;i<n;i++)//test初始化    {        char *hello = graph[i];        char *p, *token;        int j = 0;        for (p = hello; ; p = NULL, j++)        {            token = strtok_s(p, ",", &save_ptr);            if (NULL == token)   break;            test[i][j] = atoi(token);        }    }    start_now = atoi(strtok_s(condition, ",", &save_ptr));//起点    printf("start_now=%d \n", start_now);    end = atoi(strtok_s(NULL, ",", &save_ptr));//终点    printf("end=%d \n", end);    line = strtok_s(NULL, ",", &save_ptr);//优先点字符串    printf("special_line=%s \n", line);    char *get, *token;    save_ptr = NULL;    int d_count = 0;    for (get = line; ; get = NULL, d_count++)    {        token = strtok_s(get, "|", &save_ptr);        if (NULL == token)   break;        demand[d_count] = atoi(token);        // printf("demand[%d]=%d \n",d_count,demand[d_count]);    }    N = d_count;    int Sort[400 * 2] = { -1 }, Max, *C, p = 0, Stemp, Etemp, *Fdemand;    for (int i = 0; i < n; i++)    {        Sort[2 * i] = test[i][1];        Sort[2 * i + 1] = test[i][2];    }//把起点和终点包含的点都算进来    Heapsort(Sort, n * 2);//对顶点进行排序    Max = Sort[2 * n - 1];    C = (int*)malloc(sizeof(int)*(Max + 1));    if (NULL == C)    {        FatalError("Out of space!!!");    }    for (int i = 0;i<2 * n;i++)    {        if (Sort[i] != Sort[i + 1])        {            C[p] = Sort[i];            p++;        }    }    printf("edge_num=%d \n", n);    printf("point_num=%d \n", p);    printf("special_num=%d \n", N);    Fdemand = (int*)malloc(sizeof(int)*(N));;    for (int i = 0;i<N;i++)    {        Stemp = BinarySearch(C, demand[i], p);        Fdemand[i] = Stemp;    }    Heapsort(Fdemand, N);    Position Pos,L;    /*for (int j = 0;j<n;j++)//邻接表插入    {        Stemp = BinarySearch(C, test[j][1], p);        Etemp = BinarySearch(C, test[j][2], p);        if (BinarySearch(Fdemand, Etemp, N) >= 0)        {            Insert(test[j][0], Stemp, Etemp, test[j][3], 1, T);//start,stop,cost,List,把3必过点插入            T->TheLists[Stemp]->ELement++;//有几个优先级的点        }        else        {            Insert(test[j][0], Stemp, Etemp, test[j][3], 0, T);//start,stop,cost,List,把3必过点插入            T->TheLists[Stemp]->ELement++;//有几个优先级的点        }    }*/////////////////////////////////////////////////////    for (int j = 0;j<n;j++)    {        Stemp = BinarySearch(C, test[j][1], p);        Etemp = BinarySearch(C, test[j][2], p);        if (BinarySearch(Fdemand, Etemp, N) >= 0)        {            L = T->TheLists[Stemp];            Pos = Find(Etemp, L);            if (NULL == Pos)            {                Insert(test[j][0], Stemp, Etemp, test[j][3], 1, T);//start,stop,cost,List,把3必过点插入                T->TheLists[Stemp]->ELement++;//有几个优先级的点            }            else            {                if (Pos->Cost > test[j][3])                {                    Delete(Pos->ELement, L);                    T->TheLists[Stemp]->ELement--;//有几个优先级的点                    Insert(test[j][0], Stemp, Etemp, test[j][3], 1, T);                    T->TheLists[Stemp]->ELement++;//有几个优先级的点                }            }        }        else        {            L = T->TheLists[Stemp];            Pos = Find(Etemp, L);            if (NULL == Pos)            {                Insert(test[j][0], Stemp, Etemp, test[j][3], 0, T);                T->TheLists[Stemp]->ELement++;//有几个优先级的点            }            else            {                if (Pos->Cost > test[j][3])                {                    Delete(Pos->ELement, L);                    T->TheLists[Stemp]->ELement--;//有几个优先级的点                    Insert(test[j][0], Stemp, Etemp, test[j][3], 0, T);//start,stop,cost,List,把3必过点插入                    T->TheLists[Stemp]->ELement++;//有几个优先级的点                }            }        }    }////////////////////////////////////////////////////    start_now = BinarySearch(C, start_now, p);    end = BinarySearch(C, end, p);    V = InitialWeighted(0, V, n);    int route = DF(V, T, Fdemand, S, N, start_now, end, result,n);//最短路径D算法         int tmp = end;    int result_count = route;//解的个数    if (route == 0) { printf("NA\n"); }    else    {        /*if (N>=16) {        result_count =0;        while (tmp != start_now)        {            result[result_count] = find_route(tmp, T, V);            result_count++;            tmp = V[tmp].Path;        }        }*/        PrintPath(end, V, C);        printf(" COST=%4d\n", V[end].Dist);        for (int i = result_count - 1;i >= 0;i--)        {            printf("%d | ", result[i]);            //record_result(result[i]);        }        printf("\n");    }    Disposable(T);    DisposeStack(S);    free(V);    free(C);    free(Fdemand);    //record_result(result[i]);}int main(){    char *topo[5000];    int edge_num;    char *demand;    int demand_num;    edge_num = read_file(topo, 5000, "topo.csv");    demand_num = read_file(&demand, 1, "demand.csv");    search_route(topo, edge_num, demand);    getchar();    return 0;}
2 0
原创粉丝点击