タイトル説明
あります(nは\)\最初はお互いを知らない人が。各朝、前に友人がなかった二人は、友達になります。
私たちは、毎晩のための旅行を計画したい\(m個\)日。各旅行で、あなたは旅行に行く人々のグループを選択する必要があります。すべての人のために、次のいずれかが保持する必要があります。
- どちらのこの人は旅行に行きません、
- あるいは、少なくとも\(k個\)彼の友人のも旅行に行きます。
友情が推移的ではないことに注意してください。場合つまり、\(\)と\(のb \)が友人としている\(B \)と\(のC \)友人がいる、それは必ずしも意味するものではありません\(\)をして、\(のC \)です友人。
毎日のために、その日の旅行に行くことができる人々の最大数を見つけます。
入出力フォーマット
入力フォーマット:
最初の行は三つの整数を含んでいる(N \)\、\(m個\) 、および\(k個の\)($2≤n≤2 10 ^5,1≤m≤2 10 ^ 5、1≤k<Nの$ ) -旅行の一人一人がグループ内に持つべき人の数、日数や友人の数。
\(I番目の\) (\(1≤i≤m\) )次の\(Mの\)線は、2つの整数を含む\(X \)と\(Y軸\)($1≤x、y≤n 、人のことを意味し、≠Y $を)× \(のx \)と\(のy \)はその日の朝に友人になる\(私は\) 。ことが保証されている\(のx \)と\(のy \)は友人が前になかったです。
出力フォーマット:
印刷正確に\(m個\)ライン、どこ\(私は\番目)それら(の\(1≤i≤mは\) )その日の夜に旅行に行くことができる人々の最大数が含まれています\ (私は\します)。
サンプル入力と出力
入力サンプル#1:
4 4 2
2 3
1 2
1 3
1 4
出力サンプル#1:
0
0
3
3
入力サンプル#2:
5 8 2
2 1
4 2
5 4
5 2
4 3
5 1
4 1
3 2
出力サンプル#2:
0
0
0
3
3
4
4
5
入力サンプル#3:
5 7 2
1 5
3 2
2 5
3 4
1 2
5 3
1 3
出力サンプル#3:
0
0
0
0
3
4
4
分析
友人間のエッジの構築を検討するので、彼らは、動的なプラス側に問題を置きます。次いで、少なくとも選択された他の点に、ある時点でこれらの点を曜日を選択\(K \)エッジ接続ストリップ。しかし、それは考慮の反対を行い、その後、行わないで。
まず、すべてのエッジの時間未満である場合度ポイントに接続されている\(k個の\)その隣接点を更新しながら、この点はいずれの場合にも選択することができない、我々は、それを直接削除します。この時点で、残りのすなわち\(M \)日の答え。
最後に、国境後方消去、統計は答えることができます。
コード
#include<set>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define il inline
#define re register
#define maxn 200005
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x){
T f=1;x=0;char c;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=x*10+(c^48);
x*=f;
}
struct edge{
int u,v;
}e[maxn];
set<int>st[maxn];
int n,m,k,cnt;
int ans[maxn],du[maxn];
bool del[maxn];
void Delete(int x){
if(du[x]>=k||del[x]) return;
del[x]=1;cnt--;
queue<int>q;
q.push(x);
while(!q.empty()){
int now=q.front();
q.pop();
for(auto y : st[now]){
du[y]--;
if(du[y]<k&&!del[y]){
q.push(y);
del[y]=1;cnt--;
}
}
}
}
int main(){
int x,y;
read(n),read(m),read(k);
cnt=n;
for(int i=1;i<=m;++i){
read(x),read(y);
e[i].u=x,e[i].v=y;
du[x]++,du[y]++;
st[x].insert(y),st[y].insert(x);
}
for(int i=1;i<=n;++i)
Delete(i);
ans[m]=cnt;
for(int i=m;i;--i){
x=e[i].u,y=e[i].v;
if(!del[x]) du[y]--;
if(!del[y]) du[x]--;
st[x].erase(y),st[y].erase(x);
Delete(x),Delete(y);
ans[i-1]=cnt;
}
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
return 0;