zoj 3500 island communication

Island Communication

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Once upon a time, human have not invented boats and planes, bridges were the most important things in communication among islands. There is a large kingdom consists of N islands. One day, a terrible war broken out in this country. Due to the war, there might be several bridges being built or destroyed in each day. Tom, one of your best friends, is a business man. People always earn lots of money during the war, and certainly Tom doesn't want to lose this chance. But he doesn't know whether he can get to one island from another island, so he comes to you for help.

Input

There are multiple cases. The first line of each case consists of two integers N and M (1≤N≤500, 1≤M≤50000), indicates the number of islands and the number of operations. The indies of the island are from 1 to N. Then comes M lines of operations. There are three kinds of operations:

  1. I x y: means they build a bridge connects island x and island y
  2. D x y: means they destroy the bridge which connects island x and island y
  3. Q x y: Tom want to know whether he can get to island y from island x

Assume there are no bridges at the beginning, and each bridge will be built at most once(means when one bridge is destroyed, you can never build it any more)

Output

In the first line, you must output the case number. And for each query, you must output "YES" if you can get to island y from island x. otherwise output "NO".

Print a blank line between cases.

Sample Input

5 9
I 1 2
I 2 3
Q 1 3
I 1 3
I 2 4
I 4 5
D 1 2
D 2 3
Q 1 5

Sample Output

Case 1:
YES
NO

Author: YANG, Kete
Submit   Status


看别人的.

50000次操作, 所以普通做法会超时.

每个边最多删除一次, 插入一次, 可以在插入边的时候同时删除边, 同时只要保证连通性就行了, 当要加入边a, b时, 假设在加边前 a 和 b 之间只有一条路, 组成这条路的边在以后某个时刻会被删掉, 让我们删掉将最早被删除的边, 再加入ab边,  这样保证了连通性, 也保证了边数尽量少, 也符合前面的假设(ab间只有一条路). 其实每个连同分量是一棵树, 边保持在O(n), 那么对图的每次遍历相当于对树的遍历, 这样就有O(n*m)的复杂度.



#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <algorithm>
#include <vector>
#include <utility>

using namespace std;

#define NODES_MAX 510
#define INPUTS_MAX 50010
#define INF 100000000

vector <vector <int> > adj;
bool isEdge [NODES_MAX][NODES_MAX];

int deleteTime [NODES_MAX][NODES_MAX];

struct Input {
    char _op;
    int _a, _b;
    Input (char op, int a, int b): _op (op), _a (a), _b (b) {}
    Input (const Input &i): _op (i._op), _a (i._a), _b (i._b) {}
};

vector <Input> input;

void InitGraph (int n) {
    adj.clear();
    adj.resize (n);
    memset (isEdge, 0, sizeof (isEdge));
}

void NewEdge (int a, int b) {
    if (isEdge [a][b]) {
        return;
    }
    adj[a].push_back (b);
    adj[b].push_back (a);
    isEdge [a][b] = isEdge [b][a] = true;
#ifdef _DEBUG
    printf ("new edge (%d====%d)\n", a, b);
#endif
}

void DeleteEdge (int a, int b) {
    if (! isEdge [a][b]) {
        return;
    }
    int i = int (find (adj[a].begin(), adj[a].end(), b) - adj[a].begin());
    swap (adj[a][i], (int &) (adj[a].back()));
    adj[a].pop_back();

    i = int (find (adj[b].begin(), adj[b].end(), a) - adj[b].begin());
    swap (adj[b][i], (int &) (adj[b].back()));
    adj[b].pop_back();

    isEdge [a][b] = isEdge [b][a] = false;
#ifdef _DEBUG
    printf ("delete edge (%d====%d)\n", a, b);
#endif
}

bool DFS (int v, int dest, int father, int &ind) {
    if (v == dest) {
        return true;
    }
    // try every edge 'v' ====> 'a'
    for (int i=0; i<int(adj[v].size()); ++i) {
        int a = adj[v][i];
        if (a != father && DFS (a, dest, v, ind)) {
            ind = min (ind, deleteTime [v][a]);
            return true;
        }
    }
    return false;
}

int main () {
    int n, m;
    while (scanf ("%d%d", &n, &m) == 2) {
        InitGraph (n);
        input.clear();
        fill (deleteTime[0], deleteTime[NODES_MAX], INF);

        for (int i=0; i<m; ++i) {
            int a, b;
            char op[2];
            scanf ("%s%d%d", op, &a, &b);
            --a, --b;
            input.push_back (Input (*op, a, b));
            if (*op == 'D') {
                deleteTime [a][b] = deleteTime [b][a] = i;
            }
        }

        static int cs = 0;
        printf (cs ? "\n" : "");
        printf ("Case %d:\n", ++cs);

        for (int i=0; i<int(input.size()); ++i) {
            if (input[i]._op == 'D') {
                DeleteEdge (input[i]._a, input[i]._b);
            } else if (input[i]._op == 'Q') {
                int t = INF;
                printf (DFS (input[i]._a, input[i]._b, -1, t) ? "YES\n" : "NO\n");
            } else {
                int t = INF;
                if (! DFS (input[i]._a, input[i]._b, -1, t)) {
                    NewEdge (input[i]._a, input[i]._b);
                } else if (t < INF) {
                    DeleteEdge (input[t]._a, input[t]._b);
                    NewEdge (input[i]._a, input[i]._b);
                }
            }
        }
    }
    return 0;
}


发布了94 篇原创文章 · 获赞 1 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章