时间限制: 1 Sec 内存限制: 64 MB
题目描述
农夫John发现做出全威斯康辛州最甜的黄油的方法:糖。
把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在奶牛上。 农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。 农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)
输入
第1行: 3个数:奶牛数N,牧场数(2<=P<=800),牧场间道路数C(1<=C<=1450)
第2行到第N+1行: 1到N头奶牛所在的牧场号
第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距离D(1<=D<=255),当然,连接是双向的
输出
一行 输出奶牛必须行走的最小的距离和
样例输入
Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
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
}
样例输出
<span id="sample_output" style="color:#333333">8
{说明:
放在4号牧场最优
} </span>
= =
首先,最短路径是要求的。
由于我只会floyd和spfa,再看这数据..
还是用spfa好了。
然后,详见代码。
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
int n,p,c,fm[805],ds[805],q[805],s=2147483640,r;
struct epc
{
int s,e,w;
}a[3005];
bool cmp(epc u,epc v)
{
if(u.s!=v.s) return u.s<v.s;
return u.e<v.e;
}
queue<int>sf;
void Sf(int x)
{
while(!sf.empty()) sf.pop();
sf.push(x);
int f,i,p;
while(!sf.empty())
{
p=sf.front();
sf.pop();
for(i=q[p];a[i].s==p;i++)
if(a[i].w+ds[p]<ds[a[i].e])
{
ds[a[i].e]=a[i].w+ds[p];
sf.push(a[i].e);
}
}
}
int main()
{
int i,j;
scanf("%d%d%d",&n,&p,&c);
for(i=1;i<=n;i++)
{
scanf("%d",&j);
fm[j]++;
}
for(i=1;i<=c*2;i+=2)
{
scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].w);
a[i+1].w=a[i].w;a[i+1].s=a[i].e;a[i+1].e=a[i].s;
}
sort(a+1,a+c*2+1,cmp);
for(i=1;i<=c*2;i++)
if(a[i].s!=a[i-1].s)
q[a[i].s]=i;
for(i=1;i<=p;i++)
{
for(j=1;j<=p;j++)
ds[j]=100000005;
ds[i]=0;
Sf(i);
r=0;
for(j=1;j<=p;j++)
r+=ds[j]*fm[j];
if(r<s) s=r;
}
printf("%d",s);
}
就像这样,58ms。
然后,强行略。
(spfa什么的自行百度吧...)

农夫John希望通过训练奶牛并利用糖来制作全威斯康辛州最甜的黄油。问题转化为在给定的牧场和路线中找到一个最优位置放置糖,以使所有奶牛到达该地点的总距离最短。
725

被折叠的 条评论
为什么被折叠?



