UVA

来源:互联网 发布:mysql数据库安装包64 编辑:程序博客网 时间:2024/06/05 14:30

题意:

给定一个图,求两个城市之间 “某个值”最小,,这个值 是这条路径生最大边权减去最小边权

思路:

对于每次的两个点,枚举最小边,然后利用 kruscal 求最小生成树的方法,当两个给定点在一个集合的时候,说明已经连通

这时候的新加的边就是最大边,此时枚举到的最小边就是最小边


思考:

这个题不难,但是我场上没能写出来,关键就是没能想到可以用枚举最小边的这个方式,加上 kruscal 的特点的方法(或许做题多了自然能想到了)

#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<set>#include<queue>#include<stack>#include<map>#define PI acos(-1.0)#define in freopen("in.txt", "r", stdin)#define out freopen("out.txt", "w", stdout)using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 1000 + 7, maxd = (1<<18)-1, mod = 1e9 + 7;const int INF = 0x7f7f7f7f;int n, m, a, b, u, v, q;int f[maxn];struct edge {    int u, v, w;} e[maxn];bool cmp(edge a, edge b) {    return a.w < b.w;}int find_(int x) {    return f[x] == x ? x : (f[x] = find_(f[x]));}int krus(int id) {    for(int i = id+1; i < m; ++i) {        f[find_(e[i].u)] = find_(e[i].v);        if(find_(u) == find_(v)) {            return e[i].w;        }    }    return INF;}int solve() {    int ans = INF, t = 0;    for(int i = 0; i < m; ++i) {        for(int i = 0; i <= n; ++i) f[i] = i;        f[e[i].u] = f[e[i].v];        if(find_(u) == find_(v)) {            return 0;        }        t = krus(i) - e[i].w;        ans = min(ans, t);    }    return ans;}int main() {    while(~scanf("%d %d", &n, &m) && n) {        for(int i = 0; i < m; ++i) {            scanf("%d %d %d", &e[i].u, &e[i].v, &e[i].w);        }        sort(e, e+m, cmp);        scanf("%d %d", &a, &b);        scanf("%d", &q);        while(q--) {            scanf("%d %d", &u, &v);            printf("%d\n",solve()+a+b );        }    }    return 0;}


原创粉丝点击