题单链接
https://vjudge.net/article/752
1. POJ-2236 Wireless Network
//https://vjudge.net/problem/POJ-2236
#include <cstdio>
#define N 1005
int f[N];
bool broken[N];
int n,d,D,p,q;
char Q[3];
int X[N],Y[N];
int Fa (int x)
{
return f[x]==x ? x : f[x]=Fa(f[x]);
}
inline int fail(int u,int v)
{
return (X[u]-X[v])*(X[u]-X[v])+(Y[u]-Y[v])*(Y[u]-Y[v])>D;
}
int main()
{
scanf("%d%d",&n,&d);
D=d*d;
for (int i=1; i<=n; i++) {
broken[i]=1;
f[i]=i;
scanf("%d%d",&X[i],&Y[i]);
}
while (scanf("%s",Q)!=EOF) {
if (Q[0]=='O') {
scanf("%d",&p);
for (int i=1; i<=n; i++) {
if (i!=p && !broken[i] && !fail(p,i)) {
f[Fa(i)]=Fa(p);
}
}
broken[p]=0;
}
else {
scanf("%d%d",&p,&q);
puts(Fa(p)==Fa(q) ? "SUCCESS" : "FAIL");
}
}
return 0;
}
2. POJ-1611 The Suspects
//https://vjudge.net/problem/POJ-1611
#include <cstdio>
#define N 30005
int f[N],vis[N];
int Fa(int x) {
return f[x]==x ? x : f[x]=Fa(f[x]);}
int n,m,ans,k,u,v,fu,fv,tmp;
int main()
{
while (1) {
scanf("%d%d",&n,&m);
if (n==0 && m==0) {
break;
}
for (int i=0; i<n; i++) {
f[i]=i;
vis[i]=0;
}
while (m--) {
scanf("%d",&k);
if (k<=0) {
continue;
}
scanf("%d",&v);
fv=Fa(v);
while (--k) {
u=v;
fu=fv;
scanf("%d",&v);
fv=Fa(v);
if (fu!=fv) {
ans--;
f[fu]=fv;
}
}
}
tmp=Fa(0);
ans=0;
for (int i=0; i<n; i++)
ans+=(Fa(i)==tmp);
printf("%d\n",ans);
}
return 0;
}
3. HDU-1213 How Many Tables
//https://vjudge.net/problem/HDU-1213
#include <cstdio>
#include <iostream>
using namespace std;
short int f[1000],T,n,m,u,v,fu,fv;
inline int Fa(int x) {
return f[x]==x ? x : f[x]=Fa(f[x]);
}
int main()
{
cin >>T;
while (T--) {
cin >>n >>m;
for (int i=0; i<n; i++) {
f[i]=i;
}
while (m--) {
cin >>u >>v;
u--,v--;
fu=Fa(u);
fv=Fa(v);
if (fu<fv) {
swap(fu,fv);
}
if (fu!=fv) {
n--;
f[fu]=fv;
}
}
cout <<n <<endl;
}
return 0;
}
4. HDU-3038 How Many Answers Are Wrong
带权并查集
写了篇博客
https://blog.csdn.net/jackypigpig/article/details/113348863
//https://vjudge.net/problem/HDU-3038
#include <cstdio>
//设当前节点为 x
//f: 指向的父节点 (f>x)
//s: 区间 (x,f] 的和 (左开右闭)
int f[200005],s[200005];
int n,m,a,b,fa,fb,z,ans;
int Fa(int x)
{
if (f[x]!=x) {
int tmp=f[x];
f[x]=Fa(tmp); //先压缩好父节点的路径,维护好其 s[] 值后才能计算当前节点的 s[] 值
s[x]+=s[tmp];
}
return f[x];
}
void init() {
ans=0;
for (int i=0; i<=n; i++) {
//注意从 0 开始,因为开区间,会用到 0
f[i]=i;
s[i]=0;
}
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF) {
init();
while (m--) {
scanf("%d%d%d",&a,&b,&z);
a--;
fa=Fa(a);
fb=Fa(b);
if (fa==fb) {
ans+=(s[a]-s[b]!=z); //判断是否失败
}
else {
f[fa]=fb;
s[fa]=z+s[b]-s[a]; //向量加减得到
}
}
printf("%d\n",ans);
}
return 0;
}
5. POJ-1182 食物链
同样,给边附一个取3模意义下的权值,来个带权值并查集即可。
//https://vjudge.net/problem/POJ-1182
#include <cstdio>
#define N 50005
int f[N]; //并查集
int g[N]; //与父亲的关系 (0:x=f 1:x>f 2:x<f)
int ans,n,k,D,a,b,fa,fb,p;
int Fa(int x)
{
if (f[x]!=x) {
int tmp=f[x];
f[x]=Fa(tmp);
g[x]=(g[x]+g[tmp])%3;
}
return f[x];
}
void init()
{
ans=0;
for (int i=1; i<=n; i++) {
f[i]=i;
g[i]=0;
}
}
int main()
{
scanf("%d%d",&n,&k);
init();
while (k--) {
scanf("%d%d%d",&D,&a,&b);
if (a>n || b>n) {
ans++;
continue;
}
p=(D==2); //a->b = p
fa=Fa(a);
fb=Fa(b);
if (fa==fb) {
ans+=((g[a]-g[b]+3)%3!=p);
}
else {
f[fa]=fb;
g[fa]=(p+g[b]-g[a]+3)%3;
}
}
printf("%d\n",ans);
return 0;
}
6.
7. POJ-1456 Supermarket
按利润从大到小一次选,能选就选,记下时间,利用并查集压缩路径。
#include <cstdio>
#include <algorithm>
#define I c[i]
using namespace std;
long long ans,n,t,f[10002],p[10002],d[10002],c[10002];
bool cmp(long long x, long long y)
{
return p[x]>p[y];
}
long long Fa(long long &x)
{
return f[x]==x ? x : f[x]=Fa(f[x]);
}
int main()
{
while (scanf("%lld",&n)==1)
{
ans=0;
for (long long i=0; i<=10000; i++)
f[i]=i;
for (long long i=1; i<=n; i++)
{
scanf("%lld%lld",&p[i],&d[i]);
c[i]=i;
}
sort(c+1,c+n+1,cmp);
for (long long i=1; i<=n; i++)
{
t=Fa(d[I]);
if (t>0)
{
ans+=p[I];
f[t]=t-1;
}
}
printf("%lld\n",ans);
}
return 0;
}
8. POJ-1733 Parity game
带权并查集
#include <cstdio>
#include <map>
using namespace std;
map<int, int> mp;
int L,Q,cnt,l[5005],r[5005],DD[5005],f[10005],v[10005];
int Fa(int x)
{
if (f[x]==x)
{
return x;
}
int tmp=f[x];
f[x]=Fa(tmp);
v[x]=(v[x]+v[tmp]+2)%2;
return f[x];
}
int main()
{
char s[8];
int fail,a,b,D,fa,fb;
while (scanf("%d",&L)==1)
{
scanf("%d",&Q);
mp.clear();
cnt=0;
fail=Q;
for (int i=1; i<=Q; i++)
{
scanf("%d%d%s",&l[i],&r[i],s);
DD[i]=(s[0]=='o');
l[i]--;
if (!mp[l[i]])
mp[l[i]]=++cnt;
if (!mp[r[i]])
mp[r[i]]=++cnt;
}
for (int i=1; i<=cnt; i++)
{
f[i]=i;
v[i]=0;
}
for (int i=1; i<=Q; i++)
{
a=mp[l[i]];
b=mp[r[i]];
fa=Fa(a);
fb=Fa(b);
D=DD[i];
if (fa==fb)
{
if ((v[a]-v[b]+2)%2!=D)
{
fail=i-1;
break;
}
}
else
{
v[fa]=(D-v[a]+v[b]+2)%2;
f[fa]=fb;
}
}
printf("%d\n",fail);
}
return 0;
}
9. POJ-1984 Navigation Nightmare
带权并查集
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 40005
using namespace std;
long long n,m,aa[N],bb[N],ll[N];
long long c[10005],cnt,k,q[10005][3];
long long a,b,l,fa,fb;
long long fx[N],fy[N],vx[N],vy[N];
char s,ss[N][2];
bool cmp(int x, int y)
{
return q[x][2]<q[y][2];
}
long long Fa(long long x, long long f[], long long v[])
{
if (f[x]==x)
{
return x;
}
long long tmp=f[x];
f[x]=Fa(tmp,f,v);
v[x]+=v[tmp];
return f[x];
}
void solve(long long A, long long B)
{
long long fxA,fxB,fyA,fyB;
fxA=Fa(A,fx,vx);
fxB=Fa(B,fx,vx);
fyA=Fa(A,fy,vy);
fyB=Fa(B,fy,vy);
if (fxA!=fxB || fyA!=fyB)
{
puts("-1");
return;
}
printf("%lld\n",abs(vx[A]-vx[B])+abs(vy[A]-vy[B]));
}
int main()
{
while (scanf("%lld%lld",&n,&m)==2)
{
for (long long i=1; i<=m; i++)
{
scanf("%lld%lld%lld%s",&aa[i],&bb[i],&ll[i],ss[i]);
if (ss[i][0]=='S' || ss[i][0]=='W')
{
ll[i]=-ll[i];
}
}
scanf("%lld",&k);
for (long long i=1; i<=k; i++)
{
scanf("%lld%lld%lld",&q[i][0],&q[i][1],&q[i][2]);
c[i]=i;
}
sort(c+1,c+k+1,cmp);
// init
for (int i=1; i<=n; i++)
{
fx[i]=fy[i]=i;
vx[i]=vy[i]=0;
}
cnt=1;
for (long long i=1; i<=m; i++)
{
a=aa[i],b=bb[i],l=ll[i],s=ss[i][0];
if (s=='E' || s=='W')
{
fa=Fa(a,fx,vx);
fb=Fa(b,fx,vx);
if (fa!=fb)
{
vx[fa]=l-vx[a]+vx[b];
fx[fa]=fb;
}
fa=Fa(a,fy,vy);
fb=Fa(b,fy,vy);
if (fa!=fb)
{
vy[fa]=vy[b]-vy[a];
fy[fa]=fb;
}
}
else
{
fa=Fa(a,fy,vy);
fb=Fa(b,fy,vy);
if (fa!=fb)
{
vy[fa]=l-vy[a]+vy[b];
fy[fa]=fb;
}
fa=Fa(a,fx,vx);
fb=Fa(b,fx,vx);
if (fa!=fb)
{
vx[fa]=vx[b]-vx[a];
fx[fa]=fb;
}
}
while (cnt<=k && q[cnt][2]==i)
{
solve(q[cnt][0],q[cnt][1]);
cnt++;
}
if (cnt>k)
{
break;
}
}
}
return 0;
}
10. POJ-2492 A Bug’s Life
#include <cstdio>
int f[2005],v[2005];
int Fa(int x)
{
if (f[x]==x)
{
return x;
}
int tmp=f[x];
f[x]=Fa(tmp);
v[x]^=v[tmp];
return f[x];
}
int main()
{
int T,n,m;
scanf("%d",&T);
for (int t=1; t<=T; t++)
{
scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++)
{
f[i]=i;
v[i]=0;
}
int fail=0,a,b,fa,fb;
for (int i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
if (fail)
{
continue;
}
fa=Fa(a);
fb=Fa(b);
if (fa==fb)
{
if (v[a]^v[b]!=1)
{
fail=1;
}
}
else
{
v[fa]=1^(v[a]^v[b]);
f[fa]=fb;
}
}
printf("Scenario #%d:\n",t);
puts(fail ? "Suspicious bugs found!" : "No suspicious bugs found!");
if (t<T)
puts("");
}
return 0;
}