题意
给你起点终点坐标,再给你最大的行走距离 b ,再给你私人汽车的排放量 c0(从起点到车站,从车站到终点都是坐私人汽车),然后再给你 t 种交通方式的排放量,最后给你 n 个车站的坐标,以及每个车站 i 可以通过 某种交通方式 m 到达车站 j .最后让你求能在行走距离不超过 b 的情况下,从起点到终点的最小排放量,如果到不了输出 -1。
思路
对于最大的行走距离 b 是一个很小的值,我们可以设 dis [ i ] [ j ] 为当前走到 x 节点,总行走距离为 j 的最小排放量.,跑一遍最短路,在 dis [ n + 1] [ i ] ( 0<=i<=b) 中取最小值就是答案
(训练的时候刘爷跟我说这个题我做过(类似的),当时我就懵了,然后我忽然就想起来,我跟着潘学长做过,但是当时没做出来,后来让我补题来着,但是当时我没有立刻补题,结果,,,我就给忘记了/(ㄒoㄒ)/~~,亏了鑫爷还写了博客,唉,这波又辜负学长们的关心了 ,可能这也是我被ybl大佬拉开的原因吧,以后要及时补题了,要不可能真的就凉凉了/(ㄒoㄒ)/~)
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
const int mod=1e6+10;
int xs,xd,ys,yd,b,c0,t,n,l,cnt;
int c[1010],head[maxn],dis[1010][110];
bool vis[1010][110];
struct node
{
int w;
int to;
int next;
}edge[maxn];
struct Node
{
int id;
int co2;
int diss;
friend bool operator < (const Node &a,const Node &b)
//重载小于号使得小的先出队列
{
if(a.co2==b.co2) return a.diss>b.diss;
else return a.co2>b.co2;
}
//如果a.co2>b.co2成立,那么结构体Node a < Node b成立。
//由于优先队列是按照从大到小排列,所以结构体b会排列到a之前,b先出
//这里注释是因为我之前一直搞不懂关于对优先队列运算符的重载
//正好借这个题好好理解一下o(╥﹏╥)o
Node(){}
Node(int a,int b,int c)
{
id=a,co2=b,diss=c;
}
};
pair<int,int>p[maxn];
void add(int u,int v,int w)
{
edge[cnt].w=w;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dis,INF,sizeof(dis));
cnt=0;
}
int getdis(int a,int b)
{
int x=p[a].first-p[b].first;
int y=p[a].second-p[b].second;
return ceil(sqrt(x*x+y*y));
}
void dijkstra()
{
priority_queue<Node>q;
dis[0][0]=0;q.push(Node(0,0,0));
while(q.size())
{
int now=q.top().id;
int ds=q.top().diss;
q.pop();
if(vis[now][ds]) continue;
vis[now][ds]=1;
for(int i=head[now];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
int diss=getdis(now,v);
int co2=diss*c[edge[i].w];
if(diss+ds>b) continue;//小优化
if(dis[v][diss+ds]>co2+dis[now][ds])
{
dis[v][diss+ds]=co2+dis[now][ds];
q.push(Node(v,dis[v][diss+ds],diss+ds));
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
init();
cin>>xs>>ys>>xd>>yd>>b>>c0>>t;
c[0]=c0;
for(int i=1;i<=t;i++) cin>>c[i];
cin>>n;
p[0].first=xs,p[0].second=ys;
p[n+1].first=xd,p[n+1].second=yd;
add(0,n+1,0);//起点终点建边
add(n+1,0,0);
for(int i=1;i<=n;i++)
{
cin>>p[i].first>>p[i].second;
add(0,i,0),add(i,0,0);//起点与车站建边
add(n+1,i,0),add(i,n+1,0);//终点与车站建边
cin>>l;
for(int j=1;j<=l;j++)
{
int id,m;
cin>>id>>m;
add(i,id+1,m);
add(id+1,i,m);
}
}
dijkstra();
int ans=INF;
for(int i=0;i<=b;i++)
ans=min(ans,dis[n+1][i]);
if(ans==INF) cout<<"-1"<<endl;
else cout<<ans<<endl;
return 0;
}