取反的最短路问题(Dijkstra)

题目描述

星农(StarFarming)公司计划要给员工发路费津贴,发放的规则是这样的:1n-1代表各个员工家的序号,n代表公司。路费津贴只发给上班的最短路与回家的最短路的总路程最长的人。该市的路建造的有些奇怪,修路只修单行道,即只允许往某一个方向通行。

现在给你城市的有向图的地图,TLG请你帮忙计算谁能得到津贴,以及他上班和回家的总路程是多少。

输入

有多组测试数据。

每组第一行输入两个整数NM。表示点的个数,与单行道的数量(可能有重复)

接下来m行,每行输入三个整数x,y,z。表示从xy城市有一条单行道,距离为z

题目保证至少一人存在来回的路径。不存在的不发津贴(班都没法好好上还想要钱?!)

1N10001≤N≤1000

1M1000001≤M≤100000

1x,yN1≤x,y≤N

1z2001≤z≤200

输出

对于每组数据,输出两个整数,分别表示获得津贴的人的序号以及总路程。(如果有多个人路程相同,取序号最小的)

样例输入

4 7
1 2 2
2 3 2
1 3 4
4 1 2
4 2 2
3 4 1
4 3 5

样例输出

1 7

提示

对于样例,

1来回需要的最短路程是71->2->3->4->1

2来回需要的最短路程是52->3->4->2

3来回需要的最短路程是53->4->2->3

所以输出1 7


题意不多说啦,挑出到公司和回家的最长路的人给他发奖金

方法:先以公司为起点,计算到各点的路径;然后将路径取反,再一个dijkstra计算公司到个点的路径就是大家上班的最短距离,两个路径相加比较一下就行


#include
#include
#include
#include 
#define INF 0x3f3f3f
using namespace std;
int cost[1009][1009];
int cost1[1009][1009];
int d[1009], d1[1009];//从顶点s出发的最短路径
bool used[1009];
int V;

void dijksra(int s)
{
    fill(d, d+V+1, INF);
    fill(used, used+V+1,false);

    d[s]=0;
    while(true)
    {
        int v=-1;
        //从尚未使用的点中选择有距离最小的点
        for(int u=1;u<=V;u++)
        {
            if(!used[u] && (v==-1 || d[u] < d[v]))//选起点
               v=u;
        }

        if(v==-1) break;
        used[v]=true;

        for(int u=1;u<=V;u++)
        {
            d[u] = min(d[u], d[v]+cost[v][u]);//遍历选离起点最短的
            //printf("%d %d\n", u, d[u]);
        }
    }
}

void dijksra2(int s)
{
    fill(d1+1, d1+V+1, INF);
    fill(used, used+V+1,false);
    d1[s]=0;
    int u, v;

    while(true)
    {
        v=-1;
        for( u=1;u<=V;u++)
        {
            if(!used[u] && (v==-1 || d1[u] < d1[v]))
                v= u;
        }
        if(v==-1) break;
        used[v] = true;

        for(u=1; u<=V;u++)
        {
            d1[u] = min(d1[u], d1[v] + cost1[v][u]);
            //printf("%d %d\n", u, d1[u]);
        }
    }

}

int main()
{
    int m;
    while(~scanf("%d%d", &V, &m))
    {
        memset(cost, INF, sizeof(cost));
        memset(cost1, INF, sizeof(cost1));

        int u, v, value;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u, &v, &value);
            cost[u][v] = min(cost[u][v], value);
            cost1[v][u] = min(cost1[v][u], value);
        }
        dijksra(V);
        dijksra2(V);

        int maxid, maxn=0;
        for(int i=1;i= INF)
            {
                d[i]=0;
                d1[i]=0;
            }
            if(d[i]+d1[i] > maxn ) {
                maxn = d[i]+d1[i];
                maxid = i;
            }
        }

        printf("%d %d\n", maxid, d[maxid]+d1[maxid]);
    }
}




你可能感兴趣的:(最短路)