A - Environment-Friendly Travel Gym102501(二维最短路)

A - Environment-Friendly Travel Gym102501(二维最短路)_第1张图片

题意:
2维平面上,要从起点到终点,中间有n个站台,站台之间有边。两点距离为欧几里得距离。每个边可以坐不同交通工具对应不同碳排放量。
求起点到终点距离不超过B且碳排放量最小的路径

思路:
二维dijkstra,定义 d [ i ] [ j ] d[i][j] d[i][j]为到了第 i i i个点距离为 j j j时的最低碳排放量。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 1005;
const ll INF = 0x3f3f3f3f3f3f3f3f;
 
ll d[maxn][105];
int vis[1005][105],cnt,n;
int head[maxn],nex[maxn * maxn],to[maxn * maxn],tot;
ll C[maxn],B,val1[maxn * maxn],val2[maxn * maxn];
vector<pair<int,int> >G[maxn];
 
struct Node {
    int x,y;
}a[maxn];
 
struct Heap {
    int x;
    ll w1,w2;
    bool operator < (const Heap&rhs) const {
        if(w2 == rhs.w2) return w1 > rhs.w1; //距离
        return w2 > rhs.w2;  //碳排放量
    }
};
 
void add(int x,int y,ll z1,ll z2) {
    to[++tot] = y;
    nex[tot] = head[x];
    val1[tot] = z1; //距离
    val2[tot] = z2; //co2
    head[x] = tot;
}
 
void dijkstra() {
    priority_queue<Heap>Q;
    for(int i = 0;i <= n + 1;i++) {
        for(int j = 0;j <= B;j++) {
            d[i][j] = INF;
        }
    }
    d[0][0] = 0;
    Q.push({0,0,0});
    
    while(!Q.empty()) {
        Heap now = Q.top();Q.pop();
        int x = now.x,y = now.w1,z = now.w2;
        if(vis[x][y]) continue;
        vis[x][y] = 1;
        for(int j = head[x];j;j = nex[j]) {
            int v = to[j];
            int w1 = val1[j],w2 = val2[j];
            if(w1 + y > B) continue;
            if(d[v][w1 + y] > d[x][y] + w2) {
                d[v][w1 + y] = d[x][y] + w2;
                Q.push({v,w1 + y,d[v][w1 + y]});
            }
        }
    }
}
 
ll dis(Node a,Node b) {
    double x1 = a.x,y1 = a.y;
    double x2 = b.x,y2 = b.y;
    return (ll)ceil(sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));
}
 
int main() {
    Node sta,ed;
    scanf("%d%d%d%d",&sta.x,&sta.y,&ed.x,&ed.y);
    scanf("%lld%lld",&B,&C[0]);
    int T;scanf("%d",&T);
    for(int i = 1;i <= T;i++) scanf("%lld",&C[i]);
    scanf("%d",&n);
    
    a[0] = sta;a[n + 1] = ed;
    for(int i = 1;i <= n;i++) {
        int x,y,l;scanf("%d%d%d",&x,&y,&l);
        a[i].x = x;a[i].y = y;
        for(int j = 1;j <= l;j++) {
            scanf("%d%d",&x,&y);
            G[i].push_back({x,y});
        }
    }
    
    for(int i = 1;i <= n;i++) {
        for(int j = 0;j < G[i].size();j++) {
            int x = G[i][j].first,y = G[i][j].second;
            x++;
            double dist = dis(a[i],a[x]);
            add(i,x,dist,dist * C[y]);
            add(x,i,dist,dist * C[y]);
        }
    }
    
    for(int i = 1;i <= n;i++) {
        ll dist = dis(a[i],a[0]);
        add(i,0,dist,dist * C[0]);
        add(0,i,dist,dist * C[0]);
        
        dist = dis(a[i],a[n + 1]);
        add(i,n + 1,dist,dist * C[0]);
        add(n + 1,i,dist,dist * C[0]);
    }
    
    ll dist = dis(a[0],a[n + 1]);
    add(0,n + 1,dist,dist * C[0]);
    add(n + 1,0,dist,dist * C[0]);
    
    dijkstra();
    
    
    ll ans = INF;
    for(int i = 0;i <= B;i++) {
        ans = min(ans,d[n + 1][i]);
    }
    if(ans == INF) {
        printf("-1\n");
    }
    else printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(#,gym,#,最短路)