题解:将问题转化成连通分量。每次失去一座城市,切断其所有的边,算一次现在的连通分量。若增量大于1,则发出警报。
至于如何算连通分量,直接用tarjan模板
坑://我昨天晚上半夜敲的模板,把一个算所有环中最短环的tarjan模板 直接贴上去了,一直不过,还XJB改了会儿233(现在90行的代码逛逛B站随便改改就ac了2333)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<iostream> 3 #include<vector> 4 #include<queue> 5 #include<map> 6 #include<cmath> 7 #include<stack> 8 #include<string.h> 9 #include<set> 10 using namespace std; 11 const int maxn = 500 + 5; 12 vector<int> E[maxn]; 13 int dfn[maxn], low[maxn], tot, n, ans =0, vis[maxn]; 14 stack<int> S; 15 void init() { 16 for (int i = 0; i < maxn; i++) vis[i] = dfn[i] = low[i] = 0; 17 tot = 0; 18 ans = 0; 19 } 20 void tarjan(int x) { 21 low[x] = dfn[x] = ++tot; 22 S.push(x); vis[x] = 1; 23 for (int i = 0; i < E[x].size(); i++) { 24 int v = E[x][i]; 25 if (!dfn[v]) { 26 tarjan(v); 27 low[x] = min(low[x], low[v]); 28 29 } 30 else if (vis[x]) { 31 low[x] = min(low[x], dfn[v]); 32 } 33 } 34 if (low[x] == dfn[x]) { 35 //int cnt = 0; 36 while (1) { 37 int now = S.top(); 38 S.pop(); 39 vis[x] = 0; 40 //cnt++; 41 if (now == x)break; 42 } 43 ans++; 44 //if (cnt > 1)ans = min(ans, cnt); 45 } 46 } 47 set<int> st[maxn]; 48 int main() { 49 int m; 50 cin >> n >> m; 51 for (int i = 0; i < n; i++)E[i].push_back(i); 52 for (int i = 1; i <= m; i++) { 53 int x, y; 54 scanf("%d%d", &x, &y);//判重??没用 55 if (st[x].count(y) == 0) { E[x].push_back(y); st[x].insert(y); } 56 if (st[y].count(x) == 0) { E[y].push_back(x); st[y].insert(x); } 57 //E[y].push_back(x); 58 } 59 //n500m5000 60 for (int i = 1; i <= n; i++) { 61 if (!dfn[i])tarjan(i); 62 } 63 int last = ans; 64 int q; cin >> q; 65 66 for (int j = 1; j <= q; j++) { 67 int x; cin >> x; 68 int ok = 0; 69 for (int i = 0; i < E[x].size(); i++) { 70 int v = E[x][i]; 71 // for (auto t : E[v]) if (t == x)t = -1;//强行去除反向边。 72 for (vector<int>::iterator it = E[v].begin(); it != E[v].end(); it++)if (*it == x) { E[v].erase(it); break; } 73 } 74 75 E[x].clear(); 76 E[x].push_back(x); 77 init(); 78 //cout << last<< endl; 79 for (int i = 1; i <= n; i++) { 80 if (!dfn[i])tarjan(i); 81 } 82 if (ans > last + 1) ok = 1; 83 last = ans; 84 if (ok)printf("Red Alert: City %d is lost! ", x); 85 else printf("City %d is lost. ", x); 86 } 87 //cout << ans << endl; 88 if (q == n)cout << "Game Over."; 89 system("pause"); 90 }