1. 程式人生 > 其它 >題解 CF301B 【Yaroslav and Time】

題解 CF301B 【Yaroslav and Time】

技術標籤:圖論

思路:最短路

每兩個點的距離為 ( ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ ) ∗ d − a [ j ] (|x_1-x_2|+|y_1-y_2|)*d-a[j] (x1x2+y1y2)da[j],其中j為走到第j個點的可恢復的單位時間的大小
然後跑一遍dijkstra即可

#include<bits/stdc++.h>
#include<queue>
#include<vector>
using namespace std;

struct zz{
	int v;
	int w;
	bool
operator < (const zz x) const { return x.w<w; } }; vector<zz> v[2505]; int n,d,INF; int dp[2505]; int a[100005]; int x[100005]; int y[100005]; bool f[2505]; void Dijkstra(int s,int t){ dp[s]=0; priority_queue<zz> q; zz Now; Now.v=s; Now.w=dp[s]; q.push(Now); while(q.size()){ zz now=
q.top(); q.pop(); if(f[now.v]){ continue; } f[now.v]=1; int k=now.v; for(int j=0;j<v[k].size();j++){ if(dp[k]+v[k][j].w<dp[v[k][j].v]){ dp[v[k][j].v]=dp[k]+v[k][j].w; zz NOW; NOW.w=dp[v[k][j].v]; NOW.v=v[k][j].v; q.push(NOW); } } } printf("%d\n"
,dp[t]); } int main(){ memset(dp,0x3f,sizeof dp); scanf("%d%d",&n,&d); for(int i=2;i<n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ int dist=(abs(x[j]-x[i])+abs(y[j]-y[i]))*d; v[i].push_back(zz{j,dist-a[j]}); v[j].push_back(zz{i,dist-a[i]}); } } //cin>>s>>t; Dijkstra(1,n); return 0; }