目录
https://codeforces.com/contest/1549/problem/C
题意:
有个贵族,编号为1~
,编号i的贵族具有
的能量值。存在
个朋友关系,朋友关系是相互的。(如果贵族
和贵族
存在朋友关系的话,a是b的朋友,b也是a的朋友。)
一个贵族被定义为脆弱的,如果满足两个条件:
1.这个贵族至少有一个朋友
2.这个贵族的所有朋友的能量值都比他高
你需要处理以下三种类型的查询:
1.Add a friendship between nobles u and v.(添加朋友关系)
2.Remove a friendship between nobles u and v.(移除朋友关系)
3.计算剩余贵族的数量(规则:所有脆弱的贵族被杀死,同时他们的友谊也随之结束。那么,新贵族就有可能变得脆弱。这个过程会不断重复,直到没有贵族会受到伤害。)
样例输入
4 3//n个贵族,m个朋友关系
2 1//2和1是朋友
1 3
3 4
4//四次查询
3//过程3,计算剩余贵族数量
1 2 3//过程1,添加朋友关系
2 3 1
3
样例输出
//对每个过程3输出答案
2
1
思路
思维+简单模拟
1.观察:如果 a , b有朋友关系,且能量值 a < b ,那么 a就会被杀。只要存在一个朋友关系,那么这个关系中编号小的就会被杀。所以可以记录每个关系中小编号的出度,出度为 0 的就是 3 过程最后留下来的 ( 因为没有以它为小编号的关系,所以它留下来了 )。
if(x>y) swap(x,y);
deg[x]++;
2.用一个num维护贵族剩余人数。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<limits.h>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int deg[N];
int vis[N];
int main()
{
int n,m,q;
cin>>n>>m;
int num=n;//nu维护剩余人数
memset(vis,0,sizeof(vis));
while(m--)
{
int x,y;
cin>>x>>y;
if(x>y)swap(x,y);
deg[x]++;//给小编号出度加1
if(!vis[x])
{
vis[x]=1;
num--;
}
}
cin>>q;
int op,x,y;
while(q--)
{
cin>>op;
if(op==1)
{
cin>>x>>y;
if(x>y)
swap(x,y);
deg[x]++;
if(!vis[x])
{
vis[x]=1;
num--;
}
}
else if(op==2)
{
cin>>x>>y;
if(x>y)
swap(x,y);
deg[x]--;
if(deg[x]==0)
{
vis[x]=0;
num++;
}
}
else
{
cout<<num<<endl;
}
}
}