【題意】:有n個島,初始沒有橋,每次可以在i和j間建一座橋,拆一座橋,或查詢i和j是否聯通,i和j之間最多只會建一次橋。點數n=500,操作數m=50000。

【題解】:由于點數只有500,其實這題不需要任何高級的數據結構就有一個O(n*m)的算法。注意到點數很少,而要求i和j是否聯通,我們只要保留這幅圖的生成森林就足夠了,即控制邊的個數為O(n)。對于查詢操作,直接dfs一次即可。對于加邊操作,如果i和j不聯通,那么直接加上這條邊就好了。否則,加上這條邊后一定形成一個圈,如果我們把這個圈中最早被刪去的邊提前刪掉,是不會影響后面操作的結果的,所以我們刪掉這條邊,以保證圖中始終沒有圈。對于刪邊操作,如果這個邊已經被提前刪掉了,那么什么也不做,否則簡單刪掉就好了。要知道哪條邊先被刪掉,可以先讀入所有操作,預處理之。對于每次操作,復雜度均為O(n),總的復雜度O(n*m)。

【代碼】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 #include "cmath"
 8 #include "string"
 9 #include "cctype"
10 #include "map"
11 #include "iomanip"
12 #include "set"
13 #include "utility"
14 using namespace std;
15 typedef pair<intint> pii;
16 #define pb push_back
17 #define mp make_pair
18 #define fi first
19 #define se second
20 #define sof(x) sizeof(x)
21 #define lc(x) (x << 1)
22 #define rc(x) (x << 1 | 1)
23 #define lowbit(x) (x & (-x))
24 #define ll long long
25 #define maxn 550
26 #define maxm 50050
27 int n, m;
28 int a[maxm], b[maxm];
29 int d[maxn][maxn];
30 char c[maxm];
31 vector<int> vec[maxn];
32 int x, y, z;
33 
34 bool dfs(int s, int t, int fa) {
35     if(s == t) return true;
36     for(vector<int>::const_iterator it = vec[s].begin(); it != vec[s].end(); it++) {
37         if(*it != fa && dfs(*it, t, s)) {
38             if(z > d[s][*it]) {
39                 x = s;
40                 y = *it;
41                 z = d[x][y];
42             }
43             return true;
44         }
45     }
46     return false;
47 }
48 
49 int main() {
50     int Case = 1;
51     while(cin >> n >> m) {
52         for(int i = 0; i <= n; i++) {
53             vec[i].clear();
54             fill(d[i], d[i] + n, maxm);
55         }
56         for(int i = 0; i < m; i++) {
57             scanf(" %c%d%d", &c[i], &a[i], &b[i]);
58             if(c[i] == 'D') d[a[i]][b[i]] = d[b[i]][a[i]] = i;
59         }
60         if(Case > 1) puts("");
61         printf("Case %d:\n", Case++);
62         for(int i = 0; i < m; i++) {
63             if(c[i] == 'I') {
64                 z = maxm;
65                 if(dfs(a[i], b[i], -1)) {
66                     if(z < d[a[i]][b[i]]) {
67                         vec[x].erase(remove(vec[x].begin(), vec[x].end(), y), vec[x].end());
68                         vec[y].erase(remove(vec[y].begin(), vec[y].end(), x), vec[y].end());
69                         vec[a[i]].pb(b[i]);
70                         vec[b[i]].pb(a[i]);
71                     }
72                 } else {
73                     vec[a[i]].pb(b[i]);
74                     vec[b[i]].pb(a[i]);
75                 }
76             } else if(c[i] == 'D') {
77                 vec[a[i]].erase(remove(vec[a[i]].begin(), vec[a[i]].end(), b[i]), vec[a[i]].end());
78                 vec[b[i]].erase(remove(vec[b[i]].begin(), vec[b[i]].end(), a[i]), vec[b[i]].end());
79             } else {
80                 puts(dfs(a[i], b[i], -1) ? "YES" : "NO");
81             }
82         }
83     }
84     return 0;
85 }
86