USACO - 3.2.6 Sweet Butter 香甜的黄油 Dijkstra(迪杰斯特拉算法)+枚举

来源:互联网 发布:软件系统边界图 编辑:程序博客网 时间:2024/05/14 11:37

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

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

【输出格式】
一行 输出奶牛必须行走的最小的距离和.

【输入样例】

3 4 52341 2 11 3 52 3 72 4 33 4 5

【输出样例】

8

【样例图形】

         P2  P1 @--1--@ C1    \    |\     \   | \      5  7  3       \ |   \        \|    \ C3      C2 @--5--@         P3    P4{说明:放在4号牧场最优.}

【数据范围】
1 <= N <= 500
2 <= P <= 800
1 <= C <= 1450
1 <= D <= 255

思路:
枚举图上每一个点,用Dijkstra算法(或SPFA算法)计算所有点到这个点的距离和sum,再求最小值。

/*    Name: Sweet_Butter    Copyright: Twitter & Instagram @stevebieberjr    Author: @stevebieberjr    Date: 17-07-16 15:56*/#include<cstdio>#include<vector>#include<queue>#include<cstring>#define inf 0X7FFFFFFFusing namespace std;int n,p,c,cow[505],dist[805];vector<int>g[805],w[805];void init(){    scanf("%d%d%d",&n,&p,&c);    for(int i=1;i<=n;i++)    {        scanf("%d",&cow[i]); //读入奶牛所在的点    }    int x,y,z;    for(int i=1;i<=c;i++)    {        scanf("%d%d%d",&x,&y,&z);        g[x].push_back(y);        g[y].push_back(x);        w[x].push_back(z);        w[y].push_back(z);    } //建立图的存储结构}struct data{    int d,id;    friend bool operator < (data a,data b)    {        return a.d>b.d; //值大的优先级低    }};void DIJ(int s,int *d) //Dijkstra算法{    priority_queue<data>pq;    for(int i=1;i<=p;i++)    {        d[i]=inf;    }    pq.push((data){0,s});    d[s]=0;    while(!pq.empty())    {        data t=pq.top();        pq.pop();        int i=t.id;        if(t.d>d[i]) continue;        d[i]=t.d;        for(int k=0;k<g[i].size();k++)        {            int j=g[i][k],c=w[i][k];            if(d[i]+c<d[j])            {                d[j]=d[i]+c;                pq.push((data){d[j],j});            }        }    }}void solve(){    int ans=inf;    for(int i=1;i<=p;i++) //枚举每个点    {        DIJ(i,dist); //计算每个点到i点的最短路径        int sum=0;        for(int j=1;j<=n;j++)        {            sum+=dist[cow[j]]; //计算i到所有点的最短路径和        }        ans=min(ans,sum);//ans取sum的最小值    }    printf("%d\n",ans);}int main(){    init();    solve();    return 0;}
0 0
原创粉丝点击