Hack我自己
查看原帖
Hack我自己
422647
Asimplename楼主2023/4/9 18:14
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→41 \to 2 \to 3 \to 4,但是走到4时C变成1,此时L为9,那么也就比 1→3→41 \to 3 \to 4 的 L 为 2 大。所以不满足贪心

其实已经有人给过同种类的Hack了,但是管理没有处理

2023/4/9 18:14
加载中...