codeforces 1037E-Trips 【构造】

题目:戳这里

题意:n个点,每天早上会在这n个点中加一条边,每天晚上最大的子图满足子图中每个点都有k条或以上的边。

解题思路:看了官方题解,先把所有的点都连上,再从最后一天往前减边,用set维护最大的子图,注意每减去一条边时,更新该边两端点的状态。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 2e5 + 10;
 5 int ans[maxn];
 6 struct edge
 7 {
 8     int u;
 9     int v;
10 }eg[maxn];
11 int cnt[maxn];
12 int n, m, k;
13 set<int>st;
14 set<int>nu[maxn];
15 void del(int x)//更新点的状态
16 {
17     if(nu[x].size() < k && st.erase(x))
18     {
19         for(auto &i:nu[x])
20         {
21            // printf("%d %d\n", x, i);
22             nu[i].erase(x);
23             del(i);
24         }
25     }
26 }
27 int main()
28 {
29     scanf("%d %d %d", &n, &m, &k);
30     for(int i = 1; i <= m; ++i)
31     {
32         scanf("%d %d", &eg[i].u, &eg[i].v);
33         nu[eg[i].u].insert(eg[i].v);
34         nu[eg[i].v].insert(eg[i].u);
35     }
36 //    for(auto &i: nu[4])
37 //    {
38 //        printf("%d\n", i);
39 //    }
40     for(int i = 1; i <= n; ++i)
41     {
42         st.insert(i);
43     }
44     for(int i = 1; i <= n; ++i)//更新出最后一天的最大子图
45     {
46         del(i);
47     }
48     for(int i = m; i >= 1; -- i)//更新之前的
49     {
50         ans[i] = st.size();
51         if(st.empty()) break;
52         nu[eg[i].u].erase(eg[i].v);
53         nu[eg[i].v].erase(eg[i].u);
54         del(eg[i].u);
55         del(eg[i].v);
56     }
57     for(int i = 1; i <= m; ++i)
58     {
59         printf("%d\n",ans[i]);
60     }
61 }
View Code

 

posted @ 2018-09-04 18:01  euzmin  阅读(491)  评论(0编辑  收藏  举报