• Silver Cow Party POJ


    One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.

    Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.

    Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?

    Input

    Line 1: Three space-separated integers, respectively: NM, and X 
    Lines 2.. M+1: Line i+1 describes road i with three space-separated integers: AiBi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.

    Output

    Line 1: One integer: the maximum of time any one cow must walk.

    Sample Input

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

    Sample Output

    10

    Hint

    Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.
     
    题意:第一行输入n,m,x。有n个点,每个点上都有一只牛,两个点之间有通道,通道是单向的,,往下m行输入的是两个点的编号和通过通道的时间,问每个牛都去x点聚会并回来,其中牛花费的最长时间是多少。注意,去的道路可能与回来的道路不同。
     
    思路:最短路求法,但有一点不同,需要n点中除x点以外,其他点到x点又回家的时间和的最大值,可以以x为起点,从x到其他点为回家,从其他点到x为去,两个dijsktra算法即可,一个正向图,一个反向图。
     
    代码:
      1 #include <cstdio>
      2 #include <fstream>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <deque>
      6 #include <vector>
      7 #include <queue>
      8 #include <string>
      9 #include <cstring>
     10 #include <map>
     11 #include <stack>
     12 #include <set>
     13 #include <sstream>
     14 #include <iostream>
     15 #define mod 998244353
     16 #define eps 1e-6
     17 #define ll long long
     18 #define INF 0x3f3f3f3f
     19 using namespace std;
     20 
     21 //ma用来存放两个点之间的距离
     22 int ma[1010][1010];
     23 //dis用来存放到1之间的距离
     24 int  dis1[1010];
     25 int  dis2[1010];
     26 //vis数组标记已经找过的最大起重
     27 bool vis[1010];
     28 
     29 //从x到其他地方的正向图
     30 void dijkstra1(int m,int q)
     31 {
     32     memset(vis,0,sizeof(vis));
     33     memset(dis1,INF,sizeof(dis1));
     34     vis[q]=0;
     35     //初始时间为0;
     36     dis1[q]=0;
     37     for(int i=1;i<=m;i++)
     38     {
     39         int mi=INF;
     40         int k=-1;
     41         //寻找x到其他地方的最小值
     42         for(int j=1;j<=m;j++)
     43         {
     44             if(!vis[j]&&mi>dis1[j])
     45             {
     46                 mi=dis1[j];
     47                 k=j;
     48             }
     49         }
     50         //如果没有最小值,则退出循环
     51         if(k==-1)
     52         {
     53             break;
     54         }
     55         vis[k]=1;
     56         for(int j=1;j<=m;j++)
     57         {
     58             //从x到k的时间与从k到其他地方的时间之和与从x到其他地方的时间取最小值
     59             dis1[j]=min(dis1[j],dis1[k]+ma[k][j]);    
     60         }
     61     }
     62 }
     63 //从x到其他地方的反向图
     64 void dijkstra2(int m,int q)
     65 {
     66     memset(vis,0,sizeof(vis));
     67     memset(dis2,INF,sizeof(dis2));
     68     vis[q]=0;
     69     //初始时间为0;
     70     dis2[q]=0;
     71     for(int i=1;i<=m;i++)
     72     {
     73         int mi=INF;
     74         int k=-1;
     75         //寻找x到其他地方的最小值
     76         for(int j=1;j<=m;j++)
     77         {
     78             if(!vis[j]&&mi>dis2[j])
     79             {
     80                 mi=dis2[j];
     81                 k=j;
     82             }
     83         }
     84         //如果没有最小值,则退出循环
     85         if(k==-1)
     86         {
     87             break;
     88         }
     89         vis[k]=1;
     90         for(int j=1;j<=m;j++)
     91         {
     92             //从x到k的时间与从其他地方到k的时间之和与从x到其他地方的时间取最小值
     93             dis2[j]=min(dis2[j],dis2[k]+ma[j][k]);    
     94         }
     95     }
     96 }
     97 
     98 int main()
     99 {
    100     int n,m,x;
    101     scanf("%d %d %d",&n,&m,&x);
    102     int a,b,c;
    103     //因为要求的是最小时间,所以初始化为无穷
    104     memset(ma,INF,sizeof(ma));
    105     for(int i=1;i<=m;i++)
    106     {
    107         scanf("%d %d %d",&a,&b,&c);
    108         ma[a][b]=c;
    109     }
    110     //回来的
    111     dijkstra1(n,x);
    112     //去的
    113     dijkstra2(n,x);
    114     int ans=0;
    115     for(int i=1;i<=n;i++)
    116     {
    117         //所有牛花费时间中最大的一个
    118         ans=max(ans,dis1[i]+dis2[i]);
    119     }
    120     printf("%d
    ",ans);
    121 }
  • 相关阅读:
    网络相关要看的
    第四章节 树(2)
    第四章节 树(1)
    第三章节 表,栈,队列
    android动画
    面试
    人工神经网络入门(4) —— AFORGE.NET简介
    Accord.NET Framework 介绍
    DotNet 资源大全中文版
    AI Accord.NET入门
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11477897.html
Copyright © 2020-2023  润新知