P1828 香甜的黄油 Sweet Butter

题目描述

农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。

农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。

农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)

输入输出格式

输入格式:

第一行: 三个数:奶牛数N,牧场数(2<=P<=800),牧场间道路数C(1<=C<=1450)

第二行到第N+1行: 1到N头奶牛所在的牧场号

第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距离D(1<=D<=255),当然,连接是双向的

输出格式:

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

输入输出样例

输入样例#1:
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
输出样例#1:
8

说明

{样例图形

          P2  
P1 @--1--@ C1
         |
         | 
       5  7  3
         |   
         |     C3
       C2 @--5--@
          P3    P4

} {说明:

放在4号牧场最优

}

思路:SPFA+暴力,详解请看字里行间

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring> 
 4 #include<queue>
 5 #define maxn 0x7fffffff; 
 6 using namespace std;
 7 int num[10001];//储存每一个牧场上的奶牛的数量
 8 int map[1001][1001];
 9 int a[1001][1001];//邻接表
10 int numcishu[1001];//每一个点能到达的边的数量 
11 int ans=maxn;//答案;
12 int minnow;//当前的最小值
13 int dis[1001];//储存当前节点到其他节点的最短路 
14 int vis[1001];
15 queue<int>q;
16 int mc;//牧场数 
17 void spfa(int p)//计算p到其他点的路径 
18 {
19     while(q.size()!=0)q.pop();
20     memset(dis,0x7f,sizeof(dis));
21     vis[p]=1;
22     dis[p]=0;
23     q.push(p);
24     while(q.size()!=0)
25     {
26         int k=q.front();
27         for(int j=1;j<=numcishu[k];j++)
28         {
29             if(dis[a[k][j]]>dis[k]+map[k][a[k][j]])//特别注意因为是邻接表储存所以j不一定是k能到达的边 
30             {
31                 dis[a[k][j]]=dis[k]+map[k][a[k][j]];
32                 if(vis[a[k][j]]==0)
33                 {
34                     q.push(a[k][j]);
35                     vis[a[k][j]]=1;
36                 }
37             }
38         }
39         q.pop();
40         vis[k]=0;
41     }
42     minnow=0;
43     for(int i=1;i<=mc;i++)
44     {
45         minnow=minnow+dis[i]*num[i];    
46     }
47     if(minnow<ans)
48     ans=minnow;
49 }
50 int main()
51 {
52     memset(map,0x7f,sizeof(map));
53     int n;//奶牛数
54     
55     int m;//道路的数量 
56     scanf("%d%d%d",&n,&mc,&m);
57     for(int i=1;i<=n;i++)
58     {
59         int p;//奶牛所在牧场的号码
60         scanf("%d",&p);
61         num[p]++; 
62     }
63     for(int i=1;i<=m;i++)
64     {
65         int x,y,z;
66         scanf("%d%d%d",&x,&y,&z);
67         map[x][y]=map[y][x]=z;
68         a[x][++numcishu[x]]=y;
69         a[y][++numcishu[y]]=x;
70     }
71     for(int i=1;i<=mc;i++)
72     {
73         spfa(i);
74     }
75     cout<<ans;
76     return 0;
77 }
原文地址:https://www.cnblogs.com/zwfymqz/p/6689714.html