【codefroces 1037 E Trips】【圖論】【逆向思維】【好】【度大於等於k的最大子圖】
阿新 • • 發佈:2018-12-09
【連結】
【題意】
有n個人,一開始都不是朋友,m天每天都會有x,y成為朋友,現在他們有trip,只有他們出去玩的朋友數大於等於k才能出去,求每天出去最多的人數。朋友關係不具有傳遞性
【思路】
用set維護圖,並記錄與點相連的邊集。如果圖從無到有建邊,那麼每加入一條邊會導致與端點有邊的所有點都需要修改,並且不容易判斷,計數每天最大的size,那麼我們可能逆向思維。先建好全圖,將不符合的點刪去。從後往前刪邊,只需要刪去邊集與點集,size的大小就是答案了
【程式碼】
#include<bits./stdc++.h> using namespace std; const int maxn = 2e5 + 6; struct node { int x, y, ans; }t[maxn]; set<int>st; set<int>v[maxn]; int n, m, k; void del(int x) { if (v[x].size() < k&&st.erase(x)) { for (auto &y : v[x]) { v[y].erase(x); del(y); } } } int main() { scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= m; i++) { scanf("%d%d", &t[i].x, &t[i].y); v[t[i].x].insert(t[i].y); v[t[i].y].insert(t[i].x); } for (int i = 1; i <= n; i++) { st.insert(i); } for (int i = 1; i <= n; i++) { del(i); } for (int i = m; i; i--) { t[i].ans = st.size(); if (st.size() == 0)break; v[t[i].x].erase(t[i].y); v[t[i].y].erase(t[i].x); del(t[i].x); del(t[i].y); } for (int i = 1; i <= m; i++) { printf("%d\n", t[i].ans); } }