• CCCC L2-013. 红色警报 连通分量


    题解:将问题转化成连通分量。每次失去一座城市,切断其所有的边,算一次现在的连通分量。若增量大于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 }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放
    Npm install failed with “cannot run in wd”
    JQuery使用deferreds串行多个ajax请求
    使用HTML5的History API
    Christmas Trees, Promises和Event Emitters
    Node.js开发者最常范的10个错误
    Mongoose Schemas定义中timestamps选项的妙用
    Ubuntu上安装Robomongo及添加到启动器
    [nodemon] Internal watch failed: watch ENOSPC错误解决办法
    介绍两个Ubuntu上的桌面小工具
  • 原文地址:https://www.cnblogs.com/SuuT/p/8678176.html
Copyright © 2020-2023  润新知