题意: 给你n个城市。问你从1到n 最短花费。
除了起点和终点,每个城市都能减少ai 的花费。任意两点距离为 两点的哈曼顿距离*d;
题解: 跑一发最短路,我用的spfa,后来发现,不能用标记数组,这样复杂度就高了。还不如直接floyd 省事。复杂度都一样。
#include<bits/stdc++.h>
using namespace std;
const int inf=0xfffffff;
const int maxn=111;
typedef long long LL;
int n,t;
int a[maxn];
pair<int,int>p[maxn],p1;
struct Edge{
int v,w;
Edge(int _v=0,int _w=0):v(_v),w(_w){}
};
vector<Edge>e[maxn*maxn];
void addedge(int u,int v){
int d=abs(p[u].first-p[v].first)+abs(p[u].second-p[v].second);
e[u].push_back(Edge(v,d*t-a[v]));
e[v].push_back(Edge(u,d*t-a[u]));
}
int dis[maxn];
int vis[maxn];
void spfa(){
for(int i=0;i<=n;++i) dis[i]=inf;
queue<int>que;
while(!que.empty()) que.pop();
dis[1]=0;
que.push(1);
while(!que.empty()){
int u=que.front();
que.pop();
for(int i=0;i<e[u].size();++i){
int v=e[u][i].v;
if(dis[v]>dis[u]+e[u][i].w){//printf("%d->%d %d %d\n",u,v,dis[v],dis[u]+e[u][i].w);
dis[v]=dis[u]+e[u][i].w;
que.push(v);
}
}
}
}
int main()
{
scanf("%d %d",&n,&t);
a[1]=a[n]=0;
for(int i=2;i<n;++i) scanf("%d",&a[i]);
for(int i=1;i<=n;++i) scanf("%d %d",&p[i].first,&p[i].second);
for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j) addedge(i,j);
spfa();
printf("%d\n",dis[n]);
return 0;
}