洛谷1828 香甜的黄油
本题地址: http://www.luogu.org/problem/show?pid=1828
题目描述
农夫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<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 7 const int maxn = 1000+10 ,maxm=1450+10; 8 const int INF=1<<30; 9 struct Edge{ 10 int v,w,next; 11 }e[maxn*maxn]; 12 int en,front[maxn]; 13 14 int n,m,C; 15 vector<int> cows; 16 17 inline void AddEdge(int u,int v,int w) { 18 en++; e[en].v=v; e[en].w=w; e[en].next=front[u]; front[u]=en; 19 } 20 21 int SPFA(int s) { 22 int inq[maxn],d[maxn]; 23 queue<int> q; 24 memset(inq,0,sizeof(inq)); 25 for(int i=1;i<=n;i++) d[i]=INF; 26 27 d[s]=0; inq[s]=1; q.push(s); 28 while(!q.empty()) { 29 int u=q.front(); q.pop(); inq[u]=0; 30 for(int i=front[u];i>=0;i=e[i].next) { 31 int v=e[i].v,w=e[i].w; 32 if(d[v]>d[u]+w) { 33 d[v]=d[u]+w; 34 if(!inq[v]) { 35 inq[v]=1; 36 q.push(v); 37 } 38 } 39 } 40 } 41 int ans=0; 42 for(int i=0;i<cows.size();i++) ans+=d[cows[i]]; 43 return ans; 44 } 45 46 int main() { 47 memset(front,-1,sizeof(front)); 48 scanf("%d%d%d",&C,&n,&m); 49 int x; 50 for(int i=0;i<C;i++){ 51 scanf("%d",&x); 52 cows.push_back(x); 53 } 54 int u,v,w; 55 for(int i=0;i<m;i++) { 56 scanf("%d%d%d",&u,&v,&w); 57 AddEdge(u,v,w); 58 AddEdge(v,u,w); 59 } 60 int ans=INF; 61 for(int i=1;i<=n;i++) { 62 ans=min(ans,SPFA(i)); 63 } 64 printf("%d ",ans); 65 return 0; 66 }