• USACO 3.2.6 Sweet Butter 香甜的黄油(最短路)


    Description

    农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。 农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。 农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)

    Input

    第一行: 三个数:奶牛数N,牧场数(2<=P<=800),牧场间道路数C(1<=C<=1450) 第二行到第N+1行: 1到N头奶牛所在的牧场号 第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距离D(1<=D<=255),当然,连接是双向的

    Output

    一行 输出奶牛必须行走的最小的距离和

    Sample Input

    3 4 5
    2
    3
    4
    1 2 1
    1 3 5
    2 3 7
    2 4 3
    3 4 5
    /*
    {样例图形
              P2  
     P1 @--1--@ C1
             |
             | 
           5  7  3
             |   
             |     C3
           C2 @--5--@
              P3    P4
    }
    */

    Sample Output

    8
    /*{说明:
      放在4号牧场最优
    }*/

    解题思路:最短路问题,找到一个点,所有目标点到该点的距离之和最短。我最开始想用Floyd算法,我觉得最多不就是800个点,n^3应该不超时,但还是超时了,
    对于这道题应该使用SPFA
    算法,SPFA是求最短路的算法中时间复杂度最低的算法。
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 #include <queue>
     6 #define inf 0x3f3f3f3f
     7 #define maxn 1500
     8 using namespace std;
     9 struct EDGE
    10 {
    11     int to;
    12     int v;
    13 } t;
    14 vector<EDGE>e[maxn];
    15 int n,m,z;
    16 int a[maxn];
    17 int vis[maxn];
    18 int dis[maxn];
    19 void add(int from,int to,int v)
    20 {
    21     t.to=to;
    22     t.v=v;
    23     e[from].push_back(t);
    24 }
    25 void SPFA(int s)
    26 {
    27     queue<int> q;
    28     int i;
    29     for(i=1;i<=n;i++)///每次调用的初始化
    30     {
    31         dis[i]=inf;
    32         vis[i]=0;
    33     }
    34     q.push(s);
    35     dis[s] = 0;
    36     vis[s] = 1;
    37     while(!q.empty())
    38     {
    39         int now=q.front();
    40         q.pop();
    41         vis[now]=0;///弹出队列,取消标志
    42         for(i=0;i<e[now].size();i++)
    43         {
    44             if(dis[e[now][i].to]>dis[now]+e[now][i].v)
    45             {
    46                 dis[e[now][i].to]=dis[now]+e[now][i].v;
    47                 if(!vis[e[now][i].to])///不在队列就加到队列中
    48                 {
    49                     vis[e[now][i].to]=1;
    50                     q.push(e[now][i].to);
    51                 }
    52             }
    53         }
    54     }
    55 }
    56 int main()
    57 {
    58     int from,to,v,i,j,mins,ans;
    59     scanf("%d%d%d",&z,&n,&m);
    60     for(i=1; i<=z; i++)
    61     {
    62         scanf("%d",&a[i]);
    63     }
    64     mins=inf;
    65     for(i=1; i<=m; i++)
    66     {
    67         scanf("%d%d%d",&from,&to,&v);
    68         add(from,to,v);
    69         add(to,from,v);
    70     }
    71     for(i=1; i<=n; i++)
    72     {
    73         ans=0;
    74         SPFA(i);
    75         for(j=1; j<=z; j++)
    76         {
    77             ans+=dis[a[j]];
    78         }
    79         if(ans<mins)///找最小和
    80         {
    81             mins=ans;
    82         }
    83     }
    84     printf("%d
    ",mins);
    85     return 0;
    86 }
    
    
    
    
    
  • 相关阅读:
    [.net 面向对象编程基础] (13) 重构
    [.net 面向对象编程基础] (12) 面向对象三大特性——多态
    [.net 面向对象编程基础] (11) 面向对象三大特性——继承
    [.net 面向对象编程基础] (10) 面向对象三大特性——封装
    [.net 面向对象编程基础] (9) 类的成员(字段、属性、方法)
    [.net 面向对象编程基础] (8) 类和类的实例
    [.net 面向对象编程基础] (7) 基础中的基础——修饰符
    反向代理和正向代理区别
    Vue的路由及静态路由和动态路由的区别
    一次性讲明白vue插槽slot
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/9705780.html
Copyright © 2020-2023  润新知