原题链接
P1828
题目类型:
普
及
+
/
提
高
{\color{green}{普及+/提高}}
普及+/提高
AC记录:Accepted
题目大意
有 n n n头牛在不同的牧场,牧场之间有路线和路线的长度。现在让你找出一个牧场 k k k,使得奶牛们到牧场 k k k的总长度最短。
输入格式
第一行包含三个整数
N
,
P
,
C
N,P,C
N,P,C,分别表示奶牛数、牧场数和牧场间道路数。
第二行到第
N
+
1
N+1
N+1行,每行一个整数,其中第
i
i
i行的整数表示第
i
−
1
i-1
i−1头奶牛所在的牧场号。
第
N
+
2
N+2
N+2行到第
N
+
C
+
1
N+C+1
N+C+1行,每行包含三个整数
A
,
B
,
D
A,B,D
A,B,D,表示牧场号为
A
A
A和
B
B
B的两个牧场之间有一条长度为
D
D
D的双向道路相连。
输出格式
输出一行一个整数,表示奶牛必须行走的最小的距离和。
S
a
m
p
l
e
\mathbf{Sample}
Sample
I
n
p
u
t
\mathbf{Input}
Input
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
8
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
样例如图所示。
把奶油放到
4
4
4牧场,
4
4
4牧场的奶牛不用走,
2
2
2牧场的奶牛要走
3
3
3距离,
3
3
3牧场的奶牛要走
5
5
5距离。所以总路程为0*1+5*1+3*1=8
。
数据范围
对于 100 % 100\% 100%的数据, 1 ≤ N ≤ 500 , 2 ≤ P ≤ 800 , 1 ≤ A , B ≤ P , 1 ≤ C ≤ 1450 , 1 ≤ D ≤ 255 1\le N\le 500,2\le P\le 800,1\le A,B\le P,1\le C\le 1450,1\le D\le 255 1≤N≤500,2≤P≤800,1≤A,B≤P,1≤C≤1450,1≤D≤255。
解题思路
第一次看到这题,第一时间就想到的是
F
l
o
y
e
d
Floyed
Floyed算法,但是
F
l
o
y
e
d
Floyed
Floyed算法的时间复杂度为
Θ
(
n
3
)
\Theta(n^3)
Θ(n3),虽然可以接受,但是最后还要用
Θ
(
n
)
\Theta(n)
Θ(n)的时间来遍历每个牧场的奶牛个数,时间复杂度瞬间上升到
Θ
(
n
4
)
\Theta(n^4)
Θ(n4),绝对超时。所以这题可以用
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra或者
S
p
f
a
Spfa
Spfa做。
这里作者用的是堆优化的
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra,显然,我们只需要枚举放奶油的牧场,做
n
n
n遍
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra,再把答案统计起来,就可以得出答案。时间复杂度
Θ
(
n
(
n
+
m
)
log
2
n
)
\Theta(n(n+m)\log_2n)
Θ(n(n+m)log2n)。
如果有不会
F
l
o
y
e
d
Floyed
Floyed或
D
i
j
k
s
t
r
a
Dijkstra
Dijkstra的同学,可以
C
l
i
c
k
h
e
r
e
\color{red}{C}\color{orange}{l}\color{yellow}{i}\color{lightgreen}{c}\color{green}{k}\ \color{lightblue}{h}\color{blue}{e}\color{purple}{r}\color{plnk}{e}
Click here。
最后,祝大家早日
上代码
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
vector<pair<int,int> > road[810];
int cow[810];
int n,m,k;
int work(int f)
{
priority_queue<pair<int,int> > pq;
bool vis[810];
int dist[810];
memset(dist,0x7f,sizeof(dist));
memset(vis,false,sizeof(vis));
dist[f]=0;
vis[f]=true;
pq.push(make_pair(0,f));
while(pq.size())
{
pair<int,int> now=pq.top();
pq.pop();
int step=-now.first,id=now.second;
if(dist[id]!=step)
continue;
for(int i=0; i<road[id].size(); i++)
{
int temp=road[id][i].first;
int val=road[id][i].second;
if(dist[temp]>dist[id]+val)
{
dist[temp]=dist[id]+val;
pq.push(make_pair(-dist[temp],temp));
}
}
}
int sum=0;
for(int i=1; i<=n; i++)
sum+=cow[i]*dist[i];
return sum;
}
int main()
{
cin>>k>>n>>m;
for(int i=1; i<=k; i++)
{
int x;
cin>>x;
cow[x]++;
}
for(int i=1; i<=m; i++)
{
int x,y,z;
cin>>x>>y>>z;
road[x].push_back(make_pair(y,z));
road[y].push_back(make_pair(x,z));
}
int tar=0x7fffffff;
for(int i=1; i<=n; i++)
tar=min(tar,work(i));
cout<<tar<<endl;
return 0;
}
完美切题 ∼ \sim ∼