题意:
所有电脑遭到攻击,需逐个修复,每次修复一台电脑,每台电脑的坐标为(xi,yi),当两台电脑A,B都修复好且它们之间的距离小于等于d,A,B联通,或者存在一台电脑 C, A,B,C都修复好且A,C之间的距离小于等于d,B,C距离小于等于d,那么A,B联通。操作符“O”代表修复电脑,操作符“S”代表查询。
题解:
suc数组记录修理好的电脑的序号,如果两台电脑联通,那么使用并查集记录,将这两台电脑合并到一起表示联通,查询时只需判断是否为相同父亲节点即可。
AC_Code:
//
//Write by Yuan Xilan on 2019...
//
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#include<vector>
#include<limits.h>
#include<assert.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORS(I, S) for (int I = 0; S[I]; ++I)
#define RS(X) scanf("%s", (X))
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll,LL;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
void R() {}
#ifdef HOME
#define DEBUG(...) {printf("# ");printf(__VA_ARGS__);puts("");}
#else
#define DEBUG(...)
#endif
const int maxn = 1009;
int father[maxn];
int suc[maxn];//修理好的电脑
double x[maxn], y[maxn];
int n,d;
double __distance(int a, int b){
return sqrt((y[b] - y[a]) * (y[b] - y[a]) + (x[b] - x[a]) * (x[b] - x[a]));
}
void init(){
for(int i=1; i<=1008; ++i){
father[i] = i;
}
}
int get_father(int a){
if(father[a] == a){
return a;
}
return father[a] = get_father(father[a]);
}
void merge(int a, int b){
a = get_father(a);
b = get_father(b);
if(a != b){
father[a] = b;
}
}
int main(){
while(cin >> n >> d){
int cnt = 0;
init();
double tx,ty;
for(int i=1; i<=n; ++i){
cin >> tx >> ty;
x[i] = tx;
y[i] = ty;
}
char ch;
while(cin >> ch){
switch(ch){
case 'O':
int k;
cin >> k;
for(int i=0; i<cnt; ++i){
if(__distance(k, suc[i]) <= d){
merge(k,suc[i]);
}
}
suc[cnt++] = k;
break;
case 'S':
int a,b;
cin >> a >> b;
if(get_father(a) == get_father(b)) puts("SUCCESS");
else puts("FAIL");
}
}
}
}
题意:小明感染上病毒,只要是同个小组的就有可能感染病毒,有m个小组,问最多可能感染数目。
题解:
并查集模版。
//
//Write by Yuan Xilan on 2019...
//
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#include<vector>
#include<limits.h>
#include<assert.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORS(I, S) for (int I = 0; S[I]; ++I)
#define RS(X) scanf("%s", (X))
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll,LL;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
void R() {}
#ifdef HOME
#define DEBUG(...) {printf("# ");printf(__VA_ARGS__);puts("");}
#else
#define DEBUG(...)
#endif
const int maxn = 34567;
int father[maxn];
int src[maxn];
int n,m;
void init(){
for(int i=0; i<=34555; ++i){
father[i] = i;
}
}
int get_father(int x){
if(father[x] == x) return x;
return father[x] = get_father(father[x]);
}
void merge(int x, int y){
x = get_father(x);
y = get_father(y);
if(x != y){
father[x] = y;
}
}
int main(){
while(cin >> n >> m){
if(n == 0 && m == 0) break;
init();
while(m--){
int k,h,j;
cin >> k;
cin >> h;
for(int i=2; i<=k; ++i){
cin >> j;
merge(h,j);
}
}
int sum = 1;
for(int i=1; i<=n; ++i){
if(get_father(i) == get_father(0)) sum += 1;
}
cout << sum << endl;
}
}
题意:
n个人,有m组关系,互相认识的可以坐在一起吃饭,问最少的桌子数。
题解:
并查集裸体。
//
//Write by Yuan Xilan on 2019...
//
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#include<vector>
#include<limits.h>
#include<assert.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORS(I, S) for (int I = 0; S[I]; ++I)
#define RS(X) scanf("%s", (X))
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll,LL;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
void R() {}
#ifdef HOME
#define DEBUG(...) {printf("# ");printf(__VA_ARGS__);puts("");}
#else
#define DEBUG(...)
#endif
const int maxn = 34567;
int father[maxn];
int src[maxn];
int n,m,t;
void init(){
for(int i=0; i<=34555; ++i){
father[i] = i;
}
}
int get_father(int x){
if(father[x] == x) return x;
return father[x] = get_father(father[x]);
}
void merge(int x, int y){
x = get_father(x);
y = get_father(y);
if(x != y){
father[x] = y;
}
}
int main(){
while(cin >> t){
while(t--){
init();
cin >> n >> m;
while(m--){
int a,b;
cin >> a >> b;
merge(a,b);
}
set<int>j;
for(int i=1; i<=n; ++i){
j.insert(get_father(i));
}
cout << j.size() << endl;
}
}
}
题意:
判断一个迷宫是不是满足从任意一个点到另一个点有且仅有一条简单路径。
题解:
并查集在合并边的时候如果有两个点的爸爸一样,那么不符合题意,又因为任意两点,所以图必须联通。
PS:此题坑点,2 3 3 2 0 0
AC_Code:
//
//Write by Yuan Xilan on 2019...
//
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#include<vector>
#include<limits.h>
#include<assert.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORS(I, S) for (int I = 0; S[I]; ++I)
#define RS(X) scanf("%s", (X))
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll,LL;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
void R() {}
#ifdef HOME
#define DEBUG(...) {printf("# ");printf(__VA_ARGS__);puts("");}
#else
#define DEBUG(...)
#endif
const int maxn = 134567;
int father[maxn];
int src[maxn];
int n,m,t;
bool flag = true;
void init(){
for(int i=1; i<=134555; ++i){
father[i] = i;
}
}
int get_father(int x){
if(father[x] == x) return x;
return father[x] = get_father(father[x]);
}
void merge(int x, int y){
x = get_father(x);
y = get_father(y);
if(x != y){
father[x] = y;
}
else flag = false;
}
int main(){
while(cin >> n >> m){
if(n == 0 && m == 0){
puts("Yes");
continue;
}
vector<int>s1;
set<int>s2;
flag = true;
init();
if(n == -1 && m == -1) break;
merge(n, m);
s1.push_back(n);
s1.push_back(m);
while(1){
cin >> n >> m;
if(n == 0 && m == 0) break;
s1.push_back(n);
s1.push_back(m);
merge(n, m);
}
for(int i=0; i<s1.size(); ++i){
s2.insert(get_father(s1[i]));
}
if(s2.size() > 1) flag = false;
if(flag) puts("Yes");
else puts("No");
}
}
题意:
判断输入是否符合一棵树的定义,树也可以是空树,因此,0 0也是一颗树。
//
//Write by Yuan Xilan on 2019...
//
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
#include<sstream>
#include<set>
#include<map>
#include<queue>
#include<bitset>
#include<vector>
#include<limits.h>
#include<assert.h>
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define REP(I, N) for (int I = 0; I < (N); ++I)
#define REPP(I, A, B) for (int I = (A); I < (B); ++I)
#define FOR(I, A, B) for (int I = (A); I <= (B); ++I)
#define FORS(I, S) for (int I = 0; S[I]; ++I)
#define RS(X) scanf("%s", (X))
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define GET_POS(c,x) (lower_bound(c.begin(),c.end(),x)-c.begin())
#define CASET int ___T; scanf("%d", &___T); for(int cs=1;cs<=___T;cs++)
#define MP make_pair
#define PB push_back
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
using namespace std;
typedef long long ll,LL;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<LL> VL;
typedef vector<PII> VPII;
typedef pair<LL,LL> PLL;
typedef vector<PLL> VPLL;
void R() {}
#ifdef HOME
#define DEBUG(...) {printf("# ");printf(__VA_ARGS__);puts("");}
#else
#define DEBUG(...)
#endif
const int maxn = 134567;
int father[maxn];
int src[maxn];
int n,m,t,times;
bool flag = true;
void init(){
for(int i=1; i<=134555; ++i){
father[i] = i;
}
}
int get_father(int x){
if(father[x] == x) return x;
return father[x] = get_father(father[x]);
}
void merge(int x, int y){
x = get_father(x);
y = get_father(y);
if(x != y){
father[x] = y;
}
else flag = false;
}
int main(){
while(cin >> n >> m){
if(n == 0 && m == 0){
cout << "Case " << ++times << " is a tree." << endl;
continue;
}
vector<int>s1;
set<int>s2;
flag = true;
init();
if(n == -1 && m == -1) break;
merge(n, m);
s1.push_back(n);
s1.push_back(m);
while(1){
cin >> n >> m;
if(n == 0 && m == 0) break;
s1.push_back(n);
s1.push_back(m);
merge(n, m);
}
for(int i=0; i<s1.size(); ++i){
s2.insert(get_father(s1[i]));
}
if(s2.size() > 1) flag = false;
cout << "Case " << ++times << " is";
if(!flag) cout << " not";
cout << " a tree.\n";
}
}