比赛的时候想到怎么做了 没调出来(感觉自己是个睿智)
给你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 }