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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章