zoukankan      html  css  js  c++  java
  • Codeforces Manthan, Codefest 18 (rated, Div. 1 + Div. 2) E.Trips

    比赛的时候想到怎么做了 没调出来(感觉自己是个睿智)

    给你N个点M条边,这M条边是一条一条加进去的 要求你求出加入每一条边时图中极大'K度'子图的大小

    极大'K度'子图的意思是 要求出一个有尽量多的点的子图 该图中每个点的度数至少为K

    因为他每加一条边只会影响到两个点的度数 所以很明显下一个极大'K度'子图是在上一个的基础上得来的

    所以如果我们知道在最早哪一步加入边时 产生了极大'K度'子图的话 我们就可以对每条边进行判定得出答案

    但是如果每一步都判是否有极大'K度'子图 肯定会超时 该题是离线询问 所以可以考虑倒着做

    先把M条边全部加进去 再拓扑排序 每次POP出一个度数小于K的节点  在图中删掉他所连的边 直至队列为空

    得出了ans[M] 我们倒着枚举处理每条边即可

      1 /*Huyyt*/
      2 #include<bits/stdc++.h>
      3 #define mem(a,b) memset(a,b,sizeof(a))
      4 #define pb push_back
      5 using namespace std;
      6 typedef long long ll;
      7 typedef unsigned long long ull;
      8 using namespace std;
      9 vector<int> tree[200005];
     10 pair<int, int> edge[200005];
     11 int ans[200005];
     12 int du[200005];
     13 queue<int> que;
     14 bool vis[200005];
     15 map<pair<int, int>, int> mp;
     16 int main()
     17 {
     18         ios_base::sync_with_stdio(0);
     19         cin.tie(0);
     20 
     21         int n, m, k;
     22         int u, v;
     23         cin >> n >> m >> k;
     24         for (int i = 1; i <= m; i++)
     25         {
     26                 cin >> u >> v;
     27                 edge[i].first = u, edge[i].second = v;
     28                 du[v]++, du[u]++;
     29                 tree[u].pb(v), tree[v].pb(u);
     30         }
     31         for (int i = 1; i <= n; i++)
     32         {
     33                 if (du[i] < k)
     34                 {
     35                         que.push(i);
     36                         vis[i] = true;
     37                 }
     38         }
     39         while (que.size())
     40         {
     41                 int now = que.front();
     42                 que.pop();
     43                 for (auto v : tree[now])
     44                 {
     45                         if (mp[make_pair(now, v)])
     46                         {
     47                                 continue;
     48                         }
     49                         du[v]--;
     50                         mp[make_pair(now, v)] = mp[make_pair(v, now)] = 1;
     51                         if (du[v] < k && (!vis[v]))
     52                         {
     53                                 vis[v] = true;
     54                                 que.push(v);
     55                         }
     56                 }
     57         }
     58         for (int i = 1; i <= n; i++)
     59         {
     60                 if (!vis[i])
     61                 {
     62                         ans[m]++;
     63                 }
     64         }
     65         for (int i = m - 1; i >= 1; i--)
     66         {
     67                 ans[i] = ans[i + 1];
     68                 u = edge[i + 1].first, v = edge[i + 1].second;
     69                 if (mp[make_pair(u, v)])
     70                 {
     71                         continue;
     72                 }
     73                 du[u]--, du[v]--;
     74                 mp[make_pair(u, v)] = mp[make_pair(v, u)] = 1;
     75                 if (du[u] < k && (!vis[u]))
     76                 {
     77                         vis[u] = true;
     78                         que.push(u);
     79                         ans[i]--;
     80                 }
     81                 if (du[v] < k && (!vis[v]))
     82                 {
     83                         vis[v] = true;
     84                         que.push(v);
     85                         ans[i]--;
     86                 }
     87                 while (que.size())
     88                 {
     89                         int now = que.front();
     90                         que.pop();
     91                         for (auto v : tree[now])
     92                         {
     93                                 if (mp[make_pair(now, v)])
     94                                 {
     95                                         continue;
     96                                 }
     97                                 du[v]--;
     98                                 mp[make_pair(now, v)] = mp[make_pair(v, now)] = 1;
     99                                 if (du[v] < k && (!vis[v]))
    100                                 {
    101                                         ans[i]--;
    102                                         vis[v] = true;
    103                                         que.push(v);
    104                                 }
    105                         }
    106                 }
    107         }
    108         for (int i = 1; i <= m; i++)
    109         {
    110                 cout << ans[i] << endl;
    111         }
    112         return 0;
    113 }
    //E.Trips
  • 相关阅读:
    [转]C++中cin、cin.get()、cin.getline()、getline()函数的简单总结
    Assert 的用法
    [转]C/C++作用域详解
    C++ 的getline问题
    字符数组的定义与赋值
    [转] 字符数组的赋值
    [转]标准C++中的string类的用法总结
    [转]memmove、memcpy和memccpy
    关于变长数组的一点小想法-C语言定义数组但是数组长度不确定怎么办
    Java动态代理演变之路
  • 原文地址:https://www.cnblogs.com/Aragaki/p/9578394.html
Copyright © 2011-2022 走看看