题目链接:https://codeforces.com/contest/1549/problem/C
大意:
一个无向图,三种操作:
1.节点x和y之间加一条边;
2.节点x和y之间的边去掉;
3.猜测 将所有满足下列要求的节点去掉:其所有相连的节点点权都比当前节点大。重复此过程,直至没有这样的节点。
最终剩余点的个数。
思考:
发现规律:
与一节点连接的所有节点的权值只有三种情况:
1.有大有小
2.有大没小
3.有小没大
每次删点,删除的都是有大没小
的节点。
第一次删点,删除的都是有大没小
的节点。这一次删除,导致之前有大有小
的节点变成有大没小
的节点了。
第二次删点,删除的还是有大没小
的节点。同样导致一些有大有小
的节点变成有大没小
的节点。
。。。
最终,有大的点
都将被删除掉,剩下的都是没有大
的节点。
实现:
于是,只要统计有多少节点,其连接的有比其大的节点。这样的一定会被删除。
code:
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int N=400010;
int n,m,k,T,cnt,sum,flag;
int ans,t;
int f[N];
int main(){
IOS;
cin>>n>>m;
while(m--)
{
int x,y;cin>>x>>y;
if(x>y){
f[y]++;
if(f[y]==1) cnt++;
}
if(y>x){
f[x]++;
if(f[x]==1) cnt++;
}
}
cin>>m;
while(m--)
{
int k;cin>>k;
if(k==1)
{
int x,y;cin>>x>>y;
if(x>y){
f[y]++;
if(f[y]==1) cnt++;
}
else{
f[x]++;
if(f[x]==1) cnt++;
}
}
else if(k==2)
{
int x,y;cin>>x>>y;
if(x>y){
f[y]--;
if(!f[y]) cnt--;
}
else{
f[x]--;
if(!f[x]) cnt--;
}
}
else cout<<n-cnt<<endl;
}
return 0;
}
当时脑子犯迷糊了,陷到自己写的一个样例里了。想着这道题有多复杂。。
其实当时这个样例没推清楚。。