Tima goes to Xentopia(条件最短路)

Tima goes to Xentopia

Tima goes to Xentopia 题目链接

思路

首先这题应该用Dijkstra应该是无疑的,但是我们又应该如何表示不同的状态呢,我们定义了\(dis[target][red_num][blue_num]\) 来表示当前道路的状态,然后和一维的Dijkstra一样去更新其最小状态。

但是这里有一个地方需要注意直接\(dis[455][805][805]\),铁定是MLE的,通过仔细读题我们观察到 \(k1 * k2 <= 800\),于是我们可以定义一个\(dis[455][805][100]\) 的状态,如果
\(k1 < k2\) 我们就交换红蓝道路的颜色。于是这题就变成了一个Dijkstra的裸题了,但是我还是被MLE给坑了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int head[500], to[3000], nex[3000], value[3000], color[3000], cnt = 1;
ll dis[500][810][100];
int visit[500][810][100];
int n, m, s, t, k1, k2;

struct point {
    int id, r, b;
    ll dis;
    point(int _id, int _r, int _b, ll _dis) : id(_id), r(_r), b(_b), dis(_dis) {}
    bool operator < (const point & t) const {
        return dis > t.dis;
    }
};

void Dijkstra() {
    memset(dis, 0x3f, sizeof dis);
    priority_queue<point> q;
    dis[s][0][0] = 0;
    q.push(point(s, 0, 0, 0));
    while(!q.empty()) {
        point temp = q.top();
        q.pop();
        if(visit[temp.id][temp.r][temp.b])  continue;
        visit[temp.id][temp.r][temp.b] = 1;
        for(int i = head[temp.id]; i; i = nex[i]) {
            point t = point(to[i], temp.r + (color[i] == 1), temp.b + (color[i] == 2), temp.dis + value[i]);
            if(t.r > k1 || t.b > k2)    continue;//这里一定要判断,否者容易出现不必要的数据,造成数组越界,或者TLE.
            if(t.dis < dis[t.id][t.r][t.b]) {
                dis[t.id][t.r][t.b] = t.dis;
                q.push(t);
            }
        }
    }
    printf("%lld\n", dis[t][k1][k2] == INF ? -1 : dis[t][k1][k2]);
}

void add(int x, int y, int w, int c) {
    to[cnt] = y;
    nex[cnt] = head[x];
    value[cnt] = w;
    color[cnt] = c;
    head[x] = cnt++;
}

int main() {
    freopen("in.txt", "r", stdin);
    int x, y, w, c;
    scanf("%d %d %d %d", &n, &m, &k1, &k2);
    bool change = false;
    if(k1 < k2) {
        swap(k1, k2);
        change = true;
    }
    for(int i = 0; i < m; i++) {
        scanf("%d %d %d %d", &x, &y, &w, &c);
        if(change) {
            if(c == 1)  c = 2;
            else if(c == 2) c = 1;
        }
        add(x, y, w, c);
        add(y, x, w, c);
    }
    scanf("%d %d",&s, &t);
    Dijkstra();
    return 0;
}
posted @ 2020-04-30 17:26  lifehappy  阅读(184)  评论(0编辑  收藏  举报