题意:
- 每次输入一对数字,(两个数字不相等,不输入重复对),当有若干个数字对中含有的数字种类和总的数字的对数相等时候,爆炸,这时拒绝输入这一对数字,当输入单个-1时输出拒绝的次数
分析:
- 将每一对数字连线,构成一个图,我们即可发现爆炸的情况即
点数=边数
情况,即图中有环的情况,所以使用并查集判断图中有无环
- 将每一对数字连线,构成一个图,我们即可发现爆炸的情况即
AC代码:
/*************************************************************************
> File Name: D.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
> Created Time: 2017年01月13日 星期五 20时59分05秒
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
#include<vector>
#include<set>
#include<list>
#include<ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;
#define MaxN 100005
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define bug cout << 88888888 << endl;
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)
int ans,a,b;
int pre[MaxN];
int find(int x)
{
int r=x;
while(pre[r]!=r)
r=pre[r];
int i=x, j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fx]=fy;
else ans++;
}
int main()
{
while(~scanf("%d", &a))
{
while(a!=-1)
{
scanf("%d", &b);
if(pre[a] == 0) pre[a] = a;
if(pre[b] == 0) pre[b] = b;
join(a,b);
scanf("%d", &a);
}
cout << ans << endl;
ans = 0;
CLR(pre);
}
}