poj 3268

来源:互联网 发布:迅雷网络加速器手机版 编辑:程序博客网 时间:2024/06/06 03:54

题目来源:http://poj.org/problem?id=3268

本题需要用两次SPFA,来求解去和返回的最短时间。按测试样例,所画出的图,如下:


每次都是以X为源点,来进行松弛求解最短时间:

(1)以每个顶点的出边所构成的邻接表,然后求源点X到各个顶点的最短距离,这个最短距离,表示的就是,返回时从X到各个农场的最短时间。

(2)以每个顶点的入边当作出边所构成的邻接表,然后求出源点X到各个定点的最短距离,这个最短距离,表示的就是,每个农场到农场X的最短时间。

一般的求解源点到其他顶点的最短距离,所构建的邻接表都是由每个顶点的出边所构成的。

#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int INF = 10000000;const int MAXN = 1010;struct ArcNode//邻接表结构{    int to;    int weight;    ArcNode* pNext;    ArcNode()    {        to = 0;        weight = 0;        pNext = NULL;    }};ArcNode* List[MAXN];// List与ReList分别为正向图和反向图ArcNode* ReList[MAXN];int dist[MAXN];void SPFA(int n, int v0, int direction)//direction为:0表示正向图,1反向图{    queue <int> Q;    bool inq[MAXN];//标志数组,记录顶点是否在队列中    int i, u;    for(i = 0; i <= n; ++i)    {        dist[i] = INF;        inq[i] = false;    }    dist[v0] = 0;    Q.push( v0 );    while( !Q.empty())    {        u = Q.front();        Q.pop();        inq[u] = false;        ArcNode* ptr = new ArcNode;        if(direction != 0)            ptr = List[u]->pNext;        else            ptr = ReList[u]->pNext;        while( ptr != NULL )        {            int v = ptr->to;            if(dist[v] > dist[u] + ptr->weight)//松弛操作            {                dist[v] = dist[u] + ptr->weight;                if( !inq[v] )                {                    inq[v] = true;                    Q.push( v );                }            }            ptr = ptr->pNext;        }    }}void Inser_List(int u, int v, int w)//邻接表的插入操作{    ArcNode* ptr = new ArcNode;    ptr->to = v;    ptr->weight = w;    ptr->pNext = List[u]->pNext;    List[u]->pNext = ptr;    ptr = new ArcNode;    ptr->to = u;    ptr->weight = w;    ptr->pNext = ReList[v]->pNext;    ReList[v]->pNext = ptr;}void Destroy_List(int N)//释放链表{    int i;    for(i = 0; i <= N; ++i)    {        ArcNode* ptr;        ptr = List[i];        while(ptr != NULL)        {            List[i] = ptr->pNext;            delete ptr;            ptr = List[i];        }    }    for(i = 0; i <= N; ++i)    {        ArcNode* ptr;        ptr = ReList[i];        while(ptr != NULL)        {            ReList[i] = ptr->pNext;            delete ptr;            ptr = ReList[i];        }    }}int main(){    int N, M, src;    int u, v, w;    int i;    while(~scanf("%d %d %d", &N, &M, &src))    {        for(i = 0; i <= N; ++i)        {            List[i] = new ArcNode;            ReList[i] = new ArcNode;        }        for(i = 0; i < M; ++i)        {            cin>>u>>v>>w;            Inser_List(u, v, w);        }        int ans[MAXN], MaxTime = 0; //累加的最短时间以及最短时间的最大值        memset(ans, 0, sizeof(ans));        SPFA(N, src, 0);//正向求最短路        for(i = 1; i <= N; ++i)            if(i != src)//反向求最短路,并累加最短时间                ans[i] += dist[i];        SPFA(N, src, 1);        for(i = 1; i <= N; ++i)        {            if(i != src)            {                ans[i] += dist[i];                if(ans[i] > MaxTime)//在最短时间中取最大值                    MaxTime = ans[i];            }        }        cout<<MaxTime<<endl;        Destroy_List(N);    }    return 0;}


0 0
原创粉丝点击