StarFarming

来源:互联网 发布:快速背单词软件 编辑:程序博客网 时间:2024/06/14 06:06

StarFarming [最短路]

时间限制: 1 Sec 内存限制: 128 MB

提交: 456 解决: 77 统计

题目描述

星农(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 71 2 22 3 21 3 44 1 24 2 23 4 14 3 5

样例输出

1 7

提示

对于样例,

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

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

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

所以输出1 7



最短路的灵活运用:
         
                

首先我们可以先用迪杰斯特拉求出从公司到每个人家里的最短路径,

然后在把地图反转,再从公司出发,求最短路径,这个时候求的就是从每个人家到公司的最短路,

最后把两个最短路径相加求一个最大的就行,注意要特殊处理路径不存在的情况



#include <iostream>#include <cstdio>#include <queue>#include <cstring>#include <algorithm>#define INF 0x3f3f3f3fusing namespace std;int mapp1[1010][1010] , mapp2[1010][1010];int dis[2][1010];int n , m ;struct Node{  int st;  int dd;  bool friend operator < (Node a , Node b)  {   return a.dd > b.dd;   //距离大的优先级小    }}pt , qt;void  dijkstracal1()  // 回家的最短路径 { bool vis[1010] = {false}; //标记   priority_queue< Node > q;   pt.st = n;  // 起点  公司   pt.dd = 0;  // 距离  0   q.push(pt); // 进队    while(!q.empty())   {     pt = q.top();      q.pop();      if(  vis[pt.st] ) //如果被标记过        continue;      vis[pt.st] = true;      for(int i = 1; i < n; i++)      {              if( mapp1[pt.st][i] != INF)  {                  qt.st = i;  qt.dd = pt.dd + mapp1[pt.st][i];if( qt.dd < dis[0][qt.st]){             dis[0][qt.st] = qt.dd; q.push(qt);   }    }    }   } }  void  dijkstracal2()  // 上班的最短路径,反向建图 ,求公司到家的最短路径  { bool vis[1010] = {false}; //标记   priority_queue< Node > q;   pt.st = n;  // 起点  公司   pt.dd = 0;  // 距离  0   q.push(pt); // 进队    while(!q.empty())   {     pt = q.top();      q.pop();      if(  vis[pt.st] ) //如果被标记过        continue;      vis[pt.st] = true;      for(int i = 1; i < n; i++)      {              if( mapp2[pt.st][i] != INF)  {                  qt.st = i;  qt.dd = pt.dd + mapp2[pt.st][i];if( qt.dd < dis[1][qt.st]){             dis[1][qt.st] = qt.dd; q.push(qt);   }    }    }   } } int main(){       while(~scanf("%d %d",&n , &m))    {              memset(mapp1 , INF , sizeof(mapp1));            memset(mapp2 , INF , sizeof(mapp2));      memset(dis , INF , sizeof(dis));     for(int i = 0; i < m; i++)     {         int x , y , z;         scanf("%d %d %d",&x ,&y , &z);         mapp1[x][y] = min(mapp1[x][y] , z);   //有重边时取最小的  mapp2[y][x] = min(mapp2[y][x] , z); // 反向建图  } dijkstracal1();  dijkstracal2();  int ans = 0 , k;  for(int i = 1; i < n; i++)  {    if(dis[0][i] == INF || dis[1][i] == INF)     continue;     if(dis[0][i] + dis[1][i] > ans)     {            k = i;            ans = dis[0][i] + dis[1][i]; }  }  printf("%d %d\n",k ,ans);}return 0;}








原创粉丝点击