POJ 2449 Remmarguts' Date A*算法

    技术2022-05-20  42

    求第K短路径。

    在A*算法中,求最短路径时,当从优先级队列中取到目的节点时就结束了,为了求K短路径,则不结束,继续从优先级队列中取节点,直到第K次取到目的节点就是第K短路径。

    为了使用A*算法,首先要得到启发函数 f(n)=g(n)+h(n), 其中f(n) 是从初始点经由节点n到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,g(n)可以在A*算法过程中得到,h(n)是从n到目标节点最佳路径的估计代价,也就是目标节点到其他所有节点的距离,需要通过其他算法(如Dijkstra、Spfa)得到。

     

    /*Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 10006 Accepted: 2695 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story. "Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One day their neighboring country sent them Princess Uyuw on a diplomatic mission." "Erenow, the princess sent Remmarguts a letter, informing him that she would come to the hall and hold commercial talks with UDF if and only if the prince go and meet her via the K-th shortest path. (in fact, Uyuw does not want to come at all)" Being interested in the trade development and such a lovely girl, Prince Remmarguts really became enamored. He needs you - the prime minister's help! DETAILS: UDF's capital consists of N stations. The hall is numbered S, while the station numbered T denotes prince' current place. M muddy directed sideways connect some of the stations. Remmarguts' path to welcome the princess might include the same station twice or more than twice, even it is the station with number S or T. Different paths with same length will be considered disparate. Input The first line contains two integer numbers N and M (1 <= N <= 1000, 0 <= M <= 100000). Stations are numbered from 1 to N. Each of the following M lines contains three integer numbers A, B and T (1 <= A, B <= N, 1 <= T <= 100). It shows that there is a directed sideway from A-th station to B-th station with time T. The last line consists of three integer numbers S, T and K (1 <= S, T <= N, 1 <= K <= 1000). Output A single line consisting of a single integer number: the length (time required) to welcome Princess Uyuw using the K-th shortest path. If K-th shortest path does not exist, you should output "-1" (without quotes) instead. Sample Input 2 2 1 2 5 2 1 4 1 2 2 Sample Output 14 Source POJ Monthly,Zeyuan Zhu */ #include<stdio.h> #include<algorithm> #include<queue> #include<vector> using namespace std; #define MAX_VERTEX_NUM 1001 #define INFINITE 0X7FFFFFFF int gaiDistanceToTgt[MAX_VERTEX_NUM]; int giKth; int giVertexNum; struct QUEUE_NODE_ST { int iVertexId; int iDistFromSrc; friend bool operator<(QUEUE_NODE_ST a,QUEUE_NODE_ST b) { return (a.iDistFromSrc+gaiDistanceToTgt[a.iVertexId])>(b.iDistFromSrc+gaiDistanceToTgt[b.iVertexId]); } }; struct NODE { int iVertexId; int iEdgeLen; }; vector<NODE> gastGraphics[MAX_VERTEX_NUM]; vector<NODE> gastReverseGraphics[MAX_VERTEX_NUM]; void Initialize_Single_Source(int viSrcVertexId) { int iLoop; for (iLoop = 1; iLoop <= giVertexNum; iLoop++) { gaiDistanceToTgt[iLoop] = INFINITE; } gaiDistanceToTgt[viSrcVertexId] = 0; return; } void Relax(int viVertexId,int viAdjVertexId,int viEdgeLen) { if (gaiDistanceToTgt[viAdjVertexId] > gaiDistanceToTgt[viVertexId] + viEdgeLen) { gaiDistanceToTgt[viAdjVertexId] = gaiDistanceToTgt[viVertexId] + viEdgeLen; } return; } int QueueNodeCmp(const void *a,const void *b) { if (*(int *)a >= MAX_VERTEX_NUM) { return 1; } if (*(int *)b >= MAX_VERTEX_NUM) { return -1; } if (gaiDistanceToTgt[*(int *)a] > gaiDistanceToTgt[*(int *)b]) { return 1; } else { return -1; } } void Dijkstra(int viSrcVertexId) { int iVertexId; int iLoopAdjVertex; NODE stNode; int iNodeNumInQue; int aiQueue[MAX_VERTEX_NUM]; bool bVisited[MAX_VERTEX_NUM] = {false}; bool bAddNew; Initialize_Single_Source(viSrcVertexId); aiQueue[0] = viSrcVertexId; iNodeNumInQue = 1; bVisited[viSrcVertexId] = true; while(0 < iNodeNumInQue) { iVertexId = aiQueue[0];/*距离源最近的点*/ aiQueue[0] = INFINITE; bAddNew = false; for (iLoopAdjVertex = 0; iLoopAdjVertex < gastReverseGraphics[iVertexId].size(); iLoopAdjVertex++) { stNode = gastReverseGraphics[iVertexId][iLoopAdjVertex]; Relax(iVertexId,stNode.iVertexId ,stNode.iEdgeLen);/*可能会改变到源的距离*/ if(!bVisited[stNode.iVertexId]) { bVisited[stNode.iVertexId]=true; if (INFINITE == aiQueue[0]) { aiQueue[0] = stNode.iVertexId; } else { aiQueue[iNodeNumInQue] = stNode.iVertexId; iNodeNumInQue++; } bAddNew = true; } } qsort(aiQueue,iNodeNumInQue,sizeof(int ),QueueNodeCmp);/*保证出队的是最小的*/ if(!bAddNew) { iNodeNumInQue--; } } return; } void Spfa(int viSrcVertexId) { int iLoop; int iVertexId; bool abInQueue[MAX_VERTEX_NUM] = {false}; queue<int> iQueue; NODE stVertexNode; Initialize_Single_Source(viSrcVertexId); abInQueue[viSrcVertexId] = true; iQueue.push(viSrcVertexId); while(!iQueue.empty()) { iVertexId = iQueue.front(); iQueue.pop(); abInQueue[iVertexId] = false; for(iLoop = 0; iLoop < gastReverseGraphics[iVertexId].size(); iLoop++) { stVertexNode = gastReverseGraphics[iVertexId][iLoop]; if(gaiDistanceToTgt[stVertexNode.iVertexId] > gaiDistanceToTgt[iVertexId] + stVertexNode.iEdgeLen) { gaiDistanceToTgt[stVertexNode.iVertexId] = gaiDistanceToTgt[iVertexId] + stVertexNode.iEdgeLen; if(!abInQueue[stVertexNode.iVertexId]) { abInQueue[stVertexNode.iVertexId] = true; iQueue.push(stVertexNode.iVertexId); } } } } return; } int AStar(int viSrcVertexId,int viTgtVertexId) { int iLoop; int aiKCount[MAX_VERTEX_NUM] = {0}; QUEUE_NODE_ST stNode; QUEUE_NODE_ST stNode_1; priority_queue<QUEUE_NODE_ST> Queue; NODE stVertexNode; if(INFINITE == gaiDistanceToTgt[viSrcVertexId]) { return -1; } if (viSrcVertexId == viTgtVertexId) { giKth++; } /*add src vertex into queue*/ stNode.iVertexId = viSrcVertexId; stNode.iDistFromSrc = 0; Queue.push(stNode); while(!Queue.empty()) { stNode_1 = Queue.top(); Queue.pop(); aiKCount[stNode_1.iVertexId]++; if (giKth == aiKCount[viTgtVertexId]) { return stNode_1.iDistFromSrc; } if (giKth < aiKCount[stNode_1.iVertexId]) { continue; } for (iLoop = 0; iLoop < gastGraphics[stNode_1.iVertexId].size(); iLoop++) { stVertexNode = gastGraphics[stNode_1.iVertexId][iLoop]; stNode.iVertexId = stVertexNode.iVertexId ; stNode.iDistFromSrc = stNode_1.iDistFromSrc+stVertexNode.iEdgeLen ; Queue.push(stNode); } } return -1; } int main(void) { int iEdgeNum; int iSrcVertexId; int iTrgVertexId; int iEdgeLen; int iLoop; int iDistance; NODE stVertexNode; for(iLoop = 0; iLoop < MAX_VERTEX_NUM; iLoop++) { gastGraphics[iLoop].clear(); gastReverseGraphics[iLoop].clear(); } scanf("%d %d",&giVertexNum,&iEdgeNum); for(iLoop = 0; iLoop < iEdgeNum; iLoop++) { scanf("%d %d %d",&iSrcVertexId,&iTrgVertexId,&iEdgeLen); stVertexNode.iVertexId = iTrgVertexId; stVertexNode.iEdgeLen = iEdgeLen; gastGraphics[iSrcVertexId].push_back(stVertexNode); /*init reverse graphcis for Dijkstra*/ stVertexNode.iVertexId = iSrcVertexId; gastReverseGraphics[iTrgVertexId].push_back(stVertexNode); } scanf("%d %d %d",&iSrcVertexId,&iTrgVertexId,&giKth); //Dijkstra(iTrgVertexId); Spfa(iTrgVertexId); if (1 == giKth&&iSrcVertexId!= iTrgVertexId && INFINITE != gaiDistanceToTgt[iSrcVertexId]) { iDistance = gaiDistanceToTgt[iSrcVertexId]; } else { iDistance = AStar(iSrcVertexId,iTrgVertexId); } printf("%d/n",iDistance); return 0; }


    最新回复(0)