您的位置:首页 > 其它

UVA - 11165 Galactic Travel(bfs+尺取法+并查集)

2015-09-16 15:54 453 查看
题目大意:有N个星球,任意两个星球之间的距离为1,因为一次爆炸事故,有M种路被炸坏了,现在给出S和T,求S到T的最短距离

解题思路:如果直接bfs就挂了,每个点只需要被遍历一次就够了,这个可以用并查集解决,用f[i]表示下一个结点要从哪开始

用尺取法的思想,从小到大,依次判断一下能否到达该点,如果可到达的话,那么距离就加1,并将该点并入。

如果不行的话,找寻下一个点,并判断能否到达即可

[code]#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int N = 100010;

struct Forbidden{
    int v1, v2;
    Forbidden() {}
    Forbidden(int v1, int v2): v1(v1), v2(v2) {}
};

vector<Forbidden> G
;
int n, m;
int f
, vis
;

bool cmp(const Forbidden &a, const Forbidden &b) {
    return a.v1 < b.v1;
}

void init() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i <= n; i++) {
        G[i].clear();
        f[i] = i;
    }

    while (m--) {
        int u, v1, v2;
        scanf("%d%d-%d", &u, &v1, &v2);
        if (v1 > v2) swap(v1, v2);
        G[u].push_back(Forbidden(v1, v2));
    }

    for (int i = 0; i < n; i++) 
        sort(G[i].begin(), G[i].end(), cmp);

} 

int cas = 1;

int find(int x) {
    return x == f[x] ? x : f[x] = find(f[x]);
}

int bfs(int s, int e) {
    queue<int> Q;
    Q.push(s);
    vis[s] = 0;
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        //t表示第几个限制,v表示从哪开始走
        int t = 0, v = find(0);
        if (u == e) return vis[u];

        while (v < n) {
            //如果要走的点刚好时该点的话,就找寻下一个点
            if (v == u) v = find(v + 1);
            bool flag = false;
            for (int i = t; i < G[u].size(); i++) {
                if (v >= G[u][i].v1 && v <= G[u][i].v2) {
                    flag = true;
                    //找寻这个区间外的下一个点
                    v = find(G[u][i].v2 + 1);
                    t = i + 1;
                    break;
                }
            }

            //可行的点,距离+1,并将其并入下一个点,这样find该点的时候,就不会重复走了
            if (!flag) {
                vis[v] = vis[u] + 1;
                Q.push(v);
                f[v] = find(v + 1);
                v = find(v);
            }
        }
    }
    return -1;
}

void solve() {
    int s, t;
    scanf("%d%d", &s, &t);
    printf("Case #%d: ", cas++);
    int ans = bfs(s, t);
    if (ans == -1) printf("Impossible\n");
    else printf("%d\n", ans);
}

int main() {
    int test;
    scanf("%d" ,&test);
    while (test--) {
        init();
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: