poj 3268 Silver Cow Party(dijkstra最短路)

題目鏈接:http://poj.org/problem?id=3268

題目大意:給你N個農場,在X農場要舉辦一個party,其它農場需要到X農場去,然後還要回來,問N個農場中距離最遠的那個至少爲多少?,給出的邊爲單向邊。。。

思路:用dijkstra最初X農場到其它幾個農場的最短距離,然後在把邊反向,繼續求出X到其它幾個農場的最短距離,算出最大的那一個。。。


code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>

using namespace std;

const int maxn=1010;
const int INF=1000000000;


struct Edge
{
    int from,to,dist;
};

struct HeapNode
{

    int d,u;
    bool operator < (const HeapNode& rhs) const{
        return d>rhs.d;
    }
};

struct Dijkstra
{
    int n,m;                            //點數和邊數
    vector<Edge> edges;                 //邊列表
    vector<int > G[maxn];               //每個節點出發的邊編號
    bool done[maxn];                    //是否已永久標號
    int d[maxn];                        //s到各點的距離
    int p[maxn];                        //最短路中的上一條邊

    void init(int n)                    //清空
    {
        this->n=n;
        for(int i=0;i<n;i++) G[i].clear();
        edges.clear();
    }

    void AddEdge(int from,int to,int dist)     //增加邊
    {
        edges.push_back((Edge){from,to,dist});
        m=edges.size();
        G[from].push_back(m-1);
    }

    void dijkstra(int s)                  //求s到所以點的距離
    {
        priority_queue<HeapNode> Q;
        for(int i=0;i<=n;i++)
        {
            d[i]=INF;
        }
        d[s]=0;
        memset(done,0,sizeof(done));
        Q.push(HeapNode{0,s});
        while(!Q.empty())
        {
            HeapNode x=Q.top();
            Q.pop();
            int u=x.u;
            if(done[u]) continue;
            done[u]=true;
            for(int i=0;i<G[u].size();i++)
            {
                Edge& e=edges[G[u][i]];
                if(d[e.to]>d[u]+e.dist)
                {
                    d[e.to]=d[u]+e.dist;
                    p[e.to]=G[u][i];
                    Q.push((HeapNode){d[e.to],e.to});
                }
            }
        }
    }
};

int dis[1010],a[100005],b[100005],t[100005];

int main()
{
    Dijkstra D;
    int n,m,x,i;

    while(scanf("%d%d%d",&n,&m,&x)==3)
    {
        D.init(n);
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&a[i],&b[i],&t[i]);
            D.AddEdge(a[i],b[i],t[i]);
        }
        D.dijkstra(x);
        for(i=1;i<=n;i++)     //記錄x到所以邊的距離
        {
            dis[i]=D.d[i];
        }
        D.init(n);
        for(i=0;i<m;i++)      //增加反向邊
        {
            D.AddEdge(b[i],a[i],t[i]);
        }
        D.dijkstra(x);
        int maxx=0;
        for(i=1;i<=n;i++)
        {
            if(dis[i]+D.d[i]>maxx)
                maxx=dis[i]+D.d[i];
        }
        printf("%d\n",maxx);
    }
    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章