[Gym-102346A] 偷偷偷 并查集处理图(坐标)
Posted -zzz-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Gym-102346A] 偷偷偷 并查集处理图(坐标)相关的知识,希望对你有一定的参考价值。
https://vjudge.net/problem/Gym-102346A
题意:判断监控器的范围能不能阻断左下角和右上角。
分析:利用并查集处理图,能连接起来的监控器合并起来,然后在最后标记每个集合能否连接到左下、右上、左右、上下的边界形成阻断。
注意: 每个集合可以用 find( x ) 到的祖先下标标记。
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+5; const int mod=998244353; int pre[maxn]; struct node{ int x,y,l; }s[maxn]; bool check(node a,node b){ return ( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) <= (a.l+b.l)*(a.l+b.l)); } int find(int x){ if(x!=pre[x]){ pre[x] = find(pre[x]); } return pre[x]; } void Union(int x,int y){ int rx=find(x),ry=find(y); if(find(x) != find(y)){ pre[rx] = ry; } } struct Node{ int x,y,a,b; }ans[maxn]; int main() { ios::sync_with_stdio(false); cin.tie(0); int n,m,k; cin>>m>>n>>k; for(int i=1; i<=k; i++){ cin>>s[i].x>>s[i].y>>s[i].l; } for(int i=1; i<=k; i++){ pre[i] = i; } for(int i=1; i<=k-1; i++){ for(int j=i+1; j<=k; j++){ if( check(s[i],s[j]) ){ Union(i,j); } } } for(int i=1; i<=k; i++){ if(s[i].x<=s[i].l){ ans[ find(i) ].x = 1; } if(s[i].y<=s[i].l){ ans[ find(i) ].y = 1; } if(m-s[i].x<=s[i].l){ ans[ find(i) ].a = 1; } if(n-s[i].y<=s[i].l){ ans[find(i)].b = 1; } } bool ok=0; for(int i=1; i<=k; i++){ if(ans[i].x==1 && ans[i].y==1){ ok=1; } if(ans[i].a==1 && ans[i].b==1){ ok=1; } if(ans[i].x==1 && ans[i].a==1){ ok=1; } if(ans[i].y==1 && ans[i].b==1){ ok=1; } //cout<<ans[i].x<<" "<<ans[i].y<<endl; } if(ok) cout<<"N"<<endl; else cout<<"S"<<endl; }
以上是关于[Gym-102346A] 偷偷偷 并查集处理图(坐标)的主要内容,如果未能解决你的问题,请参考以下文章
Gym - 102346G Getting Confidence 最小费用最大流
Gym 102346D. Denouncing Mafia (树形dp)