NC234577. 最短路
描述
输入描述
在第一行中,先输入四个整数 ,表示宝箱、常世之荚、渊海矿髓、珊瑚蝶的个数,再输入一个整数 表示传送锚点的位置。
接下来 行,每行两个整数 ,表示宝箱的位置。
接下来 行,每行两个整数 ,表示常世之荚的位置。
接下来 行,每行两个整数 ,表示渊海矿髓的位置。
接下来 行,每行两个整数 ,表示珊瑚蝶的位置。
接下来 行,每行两个整数 ,表示传送锚点的位置。
数据保证一个位置最多只有一个宝箱、常世之荚、渊海矿髓或珊瑚蝶。
输出描述
一个实数,表示嘤嘤从初始位置 开始收集完所有物资的最短路径经过的距离。
你的答案与正确答案误差的绝对值不应超过 。
示例1
输入:
1 1 1 0 1 2 0 3 0 2 1 1 0
输出:
3.0000000000
说明:
你可以从初始位置(0,0)传送至传送锚点(1,0),然后从(1,0)移动1到达宝箱(2,0),并在(2,0)建立一个口袋锚点,再从(2,0)移动1到达常世之荚(3,0),从(3,0)传送回口袋锚点(2,0),从(2,0)移动1到达渊海矿髓(2,1),所以最短路径为3C++(g++ 7.5.0) 解法, 执行用时: 39ms, 内存消耗: 492K, 提交时间: 2022-08-18 16:46:37
#include<iostream> #include<cmath> #include<climits> #define x first #define y second using namespace std; typedef long long ll; typedef pair<ll,ll> PII; const int N=5e3+5; const ll inf=LLONG_MAX; PII p[N],q[N]; double dis[N]; bool vis[N]; int n,m; double get_dis(PII a,PII b) { return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y)); } int main() { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); scanf("%d",&m); n=a+b+c+d; for(int i=1;i<=n;++i) scanf("%lld%lld",&p[i].x,&p[i].y); for(int i=1;i<=m;++i) scanf("%lld%lld",&q[i].x,&q[i].y); PII O; O.first=0,O.second=0; for(int i=1;i<=n;++i) { dis[i]=get_dis(p[i],O); for(int j=1;j<=m;++j) dis[i]=min(dis[i],get_dis(p[i],q[j])); } // for(int i=1;i<=n;++i) // printf("%lf ",dis[i]); // puts(""); double res=0; for(int t=0;t<n;++t) { int u=-1; for(int i=1;i<=n;++i) if(!vis[i]&&(u==-1||dis[u]>dis[i])) u=i; res+=dis[u]; vis[u]=1; for(int i=1;i<=n;++i) dis[i]=min(dis[i],get_dis(p[i],p[u])); } printf("%lf\n",res); return 0; }
C++ 解法, 执行用时: 44ms, 内存消耗: 484K, 提交时间: 2022-04-01 19:30:02
#include<bits/stdc++.h> using namespace std; const int N = 2010; double dp[N]; int x[N], y[N]; bool vis[N]; double sqr(double x){ return x * x; } int main(){ int n, m; n = m = 0; for(int i=0; i<4; ++i){ scanf("%d", &m); n += m; } scanf("%d", &m); for(int i=0; i<n; ++i){ scanf("%d %d", x+i, y+i); dp[i] = sqrt(sqr(x[i]) + sqr(y[i])); } int a, b; for(int i=0; i<m; ++i){ scanf("%d %d", &a, &b); for(int j=0; j<n; ++j){ dp[j] = min(dp[j], sqrt(sqr(x[j] - a) + sqr(y[j] - b))); } } double ans = 0.0; for(int i=0; i<n; ++i){ int k = -1; for(int j=0; j<n; ++j){ if(!vis[j] && (k == -1 || dp[j] < dp[k])) k = j; } vis[k] = 1; ans += dp[k]; for(int j=0; j<n; ++j){ if(!vis[j]) dp[j] = min(dp[j], sqrt(sqr(x[j] - x[k]) + sqr(y[j] - y[k]))); } } printf("%.8f\n", ans); return 0; }