原题链接
题目大意
给你
n
n
n个点,还有每一个点与点之间的距离,并保证是双向的,即
a
i
,
j
a_{i,j}
ai,j和
a
j
,
i
a_{j,i}
aj,i是一样的。
求从
1
1
1号点到
n
n
n号点的最短距离,注意:如果要从
a
a
a号点走到
b
b
b号点,那么必须
a
<
b
a<b
a<b
S
a
m
p
l
e
\mathbf{Sample}
Sample
I
n
p
u
t
\mathbf{Input}
Input
11
0 5 3 0 0 0 0 0 0 0 0
5 0 0 1 6 3 0 0 0 0 0
3 0 0 0 8 0 4 0 0 0 0
0 1 0 0 0 0 0 5 6 0 0
0 6 8 0 0 0 0 5 0 0 0
0 3 0 0 0 0 0 0 0 8 0
0 0 4 0 0 0 0 0 0 3 0
0 0 0 5 5 0 0 0 0 0 3
0 0 0 6 0 0 0 0 0 0 4
0 0 0 0 0 8 3 0 0 0 3
0 0 0 0 0 0 0 3 4 3 0
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
13
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
目标路径为1-3-7-10-11
,路径和为3+4+3+3=13
。
解题思路
从
1
1
1号点推到
n
n
n号点,如果有路可以到某个点,就处理。
d
p
dp
dp状态转移方程如下:
设
d
p
i
dp_{i}
dpi为从
1
1
1号点开始推到
i
i
i号点的最短路径。
d
p
i
=
max
1
≤
j
≤
i
&
&
a
i
,
j
>
0
{
d
p
j
+
a
i
,
j
}
dp_{i}=\max_{1\le j\le i\&\&a_{i,j}>0}\{dp_{j}+a_{i,j}\}
dpi=1≤j≤i&&ai,j>0max{dpj+ai,j}
答案就是
d
p
n
dp_n
dpn
上代码
#include<iostream>
#include<cstring>
using namespace std;
int n;
int a[101][101];
int dp[101];
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
cin>>a[i][j];
memset(dp,0x3f3f3f3f,sizeof(dp));
dp[1]=0;
for(int i=2; i<=n; i++)
{
for(int j=i-1; j>=1; j--)
{
if(a[i][j]>0) dp[i]=min(dp[i],dp[j]+a[i][j]);
}
}
cout<<dp[n]<<endl;
return 0;
}
完美切题 ∼ \sim ∼