版权声明:欢迎转载学习! https://blog.csdn.net/m0_38081836/article/details/84068605
题意:现在有一个无向图,图上的一条边包含四个信息
- 起点
- 终点
- 距离
- 颜色(每条路线是有颜色的)
然后给出两个地点,询问从S到T经过正好 个红色路, 个蓝色路的最小距离,一条路可以走多次。
题解:
最短路的变式,搜索不知道为啥MLE了,我们需要开一个
的数组表示,到达
点经过了
个红色路线
个蓝色路线的最短距离,然后dijkstra就可以跑了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define MAXSIZE 10
#define DLEN 4
const int maxn = 1000 + 10;
const int inf = 0x3f3f3f3f;
struct Edge {
int to, next, color;
ll dis;
} edge[maxn << 1];
int first[maxn], num = 0;
ll dis[452][801][100];
void init() {
met(first, -1);
num = 0;
}
void addEdge(int u, int v, ll dis, int c) {
edge[num].to = v;
edge[num].dis = dis;
edge[num].color = c;
edge[num].next = first[u];
first[u] = num++;
}
int n, m, k1, k2, u, v, c, S, T, d;
struct Node {
Node(int _id, int _r, int _b, ll _cost) : id(_id), r(_r), b(_b), cost(_cost) {};
int id, r, b;
ll cost;
bool operator < (const Node & b) const {
return cost > b.cost;
}
};
void dijkstra() {
met(dis, -1);
priority_queue<Node> q;
q.push(Node(S, 0, 0, 0));
while(!q.empty()) {
Node now = q.top();
q.pop();
if(dis[now.id][now.r][now.b] != -1) continue;
dis[now.id][now.r][now.b] = now.cost;
for(int e = first[now.id]; e != -1; e = edge[e].next) {
Node to = Node(edge[e].to, now.r + (edge[e].color == 1), now.b + (edge[e].color == 2), now.cost + edge[e].dis);
if(to.r > k1 || to.b > k2 || dis[to.id][to.r][to.b] != -1) continue;
q.push(to);
}
}
printf("%lld\n", dis[T][k1][k2]);
}
int main() {
while(~scanf("%d%d%d%d", &n, &m, &k1, &k2)) {
init();
bool f = false;
if(k1 < k2) {
swap(k1, k2);
f = true;
}
rep(i, 1, m) {
scanf("%d%d%d%d", &u, &v, &d, &c);
if(f) {
if(c != 0)
c = (c == 1) + 1;
}
addEdge(u, v, d, c);
addEdge(v, u, d, c);
}
scanf("%d%d", &S, &T);
dijkstra();
}
return 0;
}