首页 > 代码库 > hdu1598--结题报告
hdu1598--结题报告
题解:对于输入的边,我们首先按照速度从大到小排序,然后对于每一次询问,st end 两个城市,我们暴力枚举,
for(int i = 0; i < M; i ++) 然后我们从第 i 条边开始(也就是说枚举删除0~i条边),到后面的第 M 条边,我们用krustra,向并查集中插入每一条边,看是不是能让st 和 end 联通,那么现在的 加入的这条边的速度 - 第i条边的速度就是 当前枚举情况的最小差啦,,我们与ans 比较一下取小值就可以break,进入下一条边的枚举啦。因为速度都是按小到大排序的,次条边能让st 和 end联通,再加边,只会让速度差更大
上马:
//187MS 300K #include <iostream> #include <algorithm> using namespace std; #define MAX 205 #define INF 1<<30 int N,M,Q; struct Edge { int st,end,speed; bool operator<(const Edge& E)const { return speed<E.speed; } } edge[MAX*5]; int father[MAX]; int find(int x) { if(x != father[x]) { father[x] = find(father[x]); } return father[x]; } int krustra(int st,int end) { int ans = INF; //枚举 for(int i = 0; i < M; i ++) { int j; for(j = 1; j <= N; j ++) father[j] = j; for(j = i; j < M; j ++) { father[find(edge[j].st)] = find(edge[j].end); //经过第i到第j条边的加入,我们可以使得st 和end 点联通 //并且我们早已经按速度排序,那么差值就是下面的 if(find(st) == find(end)) { int pre = edge[j].speed - edge[i].speed; if(ans > pre) ans = pre; break; } } //这里表示,从第i第M条边,都不能让st 和end 联通,那么可以break if(j == M) { break; } } return ans; } int main() { while(cin >> N >> M) { for(int i = 0; i < M ; i ++) { cin >> edge[i].st >> edge[i].end >> edge[i].speed; } sort(edge,edge+M); int ans; int st,end; cin >> Q; while (Q--) { cin >> st >> end; ans = krustra(st,end); if(ans == INF) cout << "-1" <<endl; else cout << ans <<endl; } } return 0; }个人愚昧观点,欢迎指正与讨论
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。