4 4 15
1 2 4 3
2 3 4 3
1 3 1 1
3 4 1 1
这组数据可以Hack掉以下代码:
#include<iostream>
#include<string.h>
using namespace std;
struct edge{
int l;
int c;
};
int n, m, x;
edge G[510][510];
int dis[510];
int l[510];
int c[510];
bool vis[510];
void dijkstra(){
memset(dis, 0x3f, sizeof(dis));
memset(l, 0x3f, sizeof(l));
memset(c, 0x3f, sizeof(c));
dis[1] = 0;
l[1] = 0;
for(int i = 1; i <= n; i ++){
int minn = 2e9;
int mink = 0;
for(int j = 1; j <= n; j ++){
if(dis[j] < minn && vis[j] == false){
minn = dis[j];
mink = j;
}
}
vis[mink] = true;
for(int j = 1; j <= n; j ++){
if(G[mink][j].l != 2e9){
int dist = l[mink] + G[mink][j].l + x / min(c[mink], G[mink][j].c);
if(dist < dis[j]){
dis[j] = dist;
l[j] = l[mink] + G[mink][j].l;
c[j] = min(G[mink][j].c, c[mink]);
}
}
}
}
}
int main (){
for(int i = 1; i <= 501; i ++){
for(int j = 1; j <= 501; j ++){
G[i][j].l = 2e9;
}
}
cin >> n >> m >> x;
int u,v,l,c;
for(int i = 1; i <= m; i ++){
cin >> u >> v >> l >> c;
G[u][v].l = min(G[u][v].l, l);
G[u][v].c = max(G[u][v].c, c);
G[v][u].l = min(G[v][u].l, l);
G[v][u].c = max(G[v][u].c, c);
}
dijkstra();
cout << dis[n];
return 0;
}
原因:此代码优先选择 L+X/C 最小的节点更新其他点,也就是走 1→2→3→4,但是走到4时C变成1,此时L为9,那么也就比 1→3→4 的 L 为 2 大。所以不满足贪心
其实已经有人给过同种类的Hack了,但是管理没有处理