STL的强大不得不服,应该还有更优的做法
倒着查询,刚开始把所有边和点都考虑在内,之后依次从后往前删边,然后删除不符条件的点
重点在于如何删除不符合条件的点,我用set<pair<int,int>> 存储每个点和他的度(与他相连的点数),每次删除一条边时,减少两个点的度,依次从set中取出度最小的点,删除这个点,更新其他点即可,其中多次运用到set.earse和set.inset(),感觉很流氓,强烈依靠了set的复杂度,这样的复杂度可以保持在nlogn级别
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<vector> #include<string.h> #include<cstring> #include<algorithm> #include<set> #include<map> #include<fstream> #include<cstdlib> #include<ctime> #include<list> #include<climits> #include<bitset> using namespace std; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout); #define left asfdasdasdfasdfsdfasfsdfasfdas1 #define tan asfdasdasdfasdfasfdfasfsdfasfdas typedef long long ll; typedef unsigned int un; const int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; const ll mod=1e9; const int maxn=2e6+7; const int maxm=1e6+7; const double eps=1e-4; int m,n,k; int ar[maxn]; pair<int,int> pa[maxn]; set<int> se[maxn]; set<pair<int,int> > sep; int ansl[maxn]; void update() { while(sep.size() && (*sep.begin()).first<k){ int x=(*sep.begin()).second; sep.erase(sep.begin()); for(auto au=se[x].begin();au!=se[x].end();){ int val=*au; if(sep.count(make_pair(ar[val],val))){ sep.erase(make_pair(ar[val],val)); ar[val]--; sep.insert(make_pair(ar[val],val)); se[x].erase(au++); } else au++; } } } int main() { memset(ar,0,sizeof(ar)); scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;i++){ int a,b;scanf("%d%d",&a,&b); se[a].insert(b); se[b].insert(a); pa[i]=make_pair(a,b); ar[a]++; ar[b]++; } for(int i=1;i<=n;i++)sep.insert(make_pair(ar[i],i)); update(); ansl[m]=sep.size(); for(int i=m-1;i>0;i--){ int a=pa[i].first,b=pa[i].second; //cout<<"i = "<<i<<" "<<a<<" "<<b<<endl; if(sep.count(make_pair(ar[a],a)) && sep.count(make_pair(ar[b],b))){ sep.erase(make_pair(ar[a],a)); sep.erase(make_pair(ar[b],b)); ar[a]--; ar[b]--; sep.insert(make_pair(ar[a],a)); sep.insert(make_pair(ar[b],b)); se[a].erase(b); se[b].erase(a); update(); } ansl[i]=sep.size(); } for(int i=1;i<=m;i++){ printf("%d ",ansl[i]); } return 0; }