Cpp环境【Usaco 3.2.6】【Vijos1251】Павлов的香甜黄油

来源:互联网 发布:什么叫不支持网络打印 编辑:程序博客网 时间:2024/05/20 04:09
【问题描述】  

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

【输入格式】  

第 1 行: 三个数:奶牛数 N,牧场数 P,牧场间道路数 C。
第 2 行到第 N+1 行: 1 到 N 头奶牛所在的牧场号。
第 N+2 行到第 N+C+1 行: 每行有三个数:相连的牧场A、B,两牧场间距 D,当然,连接是双向的。

【输出格式】  

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

【输入样例】  

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

【输出样例】  

8

【数据范围】  

  2 <= P <= 800
  1 <= C <= 1450
  1 <= D <= 255
  1 <= N <=500

【思路梳理】  

数据规模不大,再加上没有什么其他的好办法,所以可以依次穷举所有的牧场,假设将糖放在第i个牧场,求出第i个牧场到其他所有牧场的最小距离之和。对于枚举的所有最优结果,直接取一个最小值输出即可。
给出一个伪代码方便读者理解:

void solve(){    依次穷举每一个牧场:    将dist(距离)置为无穷大,    以该牧场为出发源使用SPFA算法/Dijstra算法求出所有点到该出发源的距离dist[i]。    将所有的距离相加,与目前最优结果进行比较。    输出最优解}

【Cpp代码】

#include<queue>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#define maxnum 505#define maxn 805#define inf 2000000005using namespace std;int num,p,c,dist[maxn],loca[maxnum],cnt=inf;vector<int>g[maxn],w[maxn];bool inq[maxn];int SPFA(int s)//改造了一下SPFA算法,让他返回距离之和,一个漏洞是可能存在有些点不能够到达使得最小距离的加和超过了int上界{    int ans=0;    memset(inq,false,sizeof(inq));    for(int i=1;i<=p;i++)   dist[i]=inf;    queue<int>q;    q.push(s);    inq[s]=true;    dist[s]=0;    while(!q.empty())    {        int i=q.front();q.pop();        inq[i]=false;        for(int j=0;j<g[i].size();j++)        {            int k=g[i][j],c=w[i][j];            if(dist[k]>dist[i]+c)            {                dist[k]=dist[i]+c;                if(!inq[k])                {                    inq[k]=true;                    q.push(k);                }            }           }    }    for(int i=1;i<=num;i++)        ans+=dist[loca[i]];    return ans; }int main(){    //freopen("in.txt","r",stdin);    cin>>num>>p>>c;    for(int i=1;i<=num;i++)//记录有奶牛的牧场的编号        scanf("%d",&loca[i]);    for(int i=1;i<=c;i++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        g[x].push_back(y);w[x].push_back(z);        g[y].push_back(x);w[y].push_back(z);//建立存储结构    }    for(int i=1;i<=p;i++)//对于每一个牧场依次枚举,使用SPFA算法求出各点的最短距离之和        cnt=min(cnt,SPFA(i));    cout<<cnt;    return 0;}
1 0