• 并查集


    Wireless Network

    题意

    N台损坏的计算机,任意两台计算机之间距离小于D即可连接,计算机最初不连接,经过若干次操作,操作一,O X ,修复X计算机,并连接所有与X距离不大于D的计算机,操作二,S P Q ,询问P,Q是否存在一条连接的线路,不存在输出FAIL,存在输出SUCCESS

    题解

    并查集求解
    vis :记录是否修复
    ms :记录任意两点距离
    per :记录祖先节点

    #pragma GCC optimize(2)
    #include <iostream>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    const int inf=0x3f3f3f3f;
    #define eps 1e-5 
    #define pii pair<int,int>
    #define FI first
    #define SE second
    #define ll long long
    #define ull unsigned long long
    const ll mod = 4294967296;/// 998244353;
    const int mxn = 1e3 +7;
    int _ , n , m , t , k ,  cnt , si , res ,ans ;
    template <class T>
    void rd(T &x){
    	T flag = 1 ; x = 0 ; char ch = getchar() ;
    	while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    	while(isdigit(ch)) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
    	x*=flag;
    }
    int to[mxn] , nx[mxn] , head[mxn] ,per[mxn],x[mxn],y[mxn] ,ms[mxn][mxn];
    char op;
    bool vis[mxn] ;
    int Find(int x) { return x==per[x]?x:per[x] = Find(per[x]); }
    void Union(int u,int v) { per[ Find(u) ] = Find(v); }
    int Dis(int i,int j){return (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ;}
    void solve()
    {
    	cin>>n>>k;
    	memset(vis,0,sizeof vis);
    	for(int i=1;i<=n;i++) cin>>x[i]>>y[i] , per[i] = i ;
    	for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) ms[i][j] = ms[j][i] = (Dis(i,j)<=k*k?1:0);
    	while(cin>>op){
    		if(op=='O') {
    			cin>>si; vis[si] = 1 ;
    			for(int i=1;i<=n;i++) {
    				if(ms[si][i] && i!=si && vis[i]){
    					int ui = Find(si) , vi = Find(i);
    					if(ui!=vi) per[ui] = vi ;
    				} 
    			}
    		} else {
    			int u,v,ui,vi;
    			cin>>u>>v;
    			ui = Find(u) , vi = Find(v) ;
    			if(ui==vi) cout<<"SUCCESS
    ";
    			else cout<<"FAIL
    ";
    		}
    	}
    }
    int main(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve();return 0;}
    

    The Suspects

    题意

    求M个集合中,和 0号 在同一集合中所有不同编号的人的个数

    题解

    并查集

    #pragma GCC optimize(2)
    #include <iostream>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    const int inf=0x3f3f3f3f;
    #define eps 1e-5 
    #define pii pair<int,int>
    #define FI first
    #define SE second
    #define ll long long
    #define ull unsigned long long
    const ll mod = 4294967296;/// 998244353;
    const int mxn = 3e4 +7;
    int _ , n , m , t , k ,  cnt , si , res ,ans ;
    template <class T>
    void rd(T &x){
    	T flag = 1 ; x = 0 ; char ch = getchar() ;
    	while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    	while(isdigit(ch)) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
    	x*=flag;
    }
    int to[mxn] , nx[mxn] , head[mxn] ,per[mxn],x[mxn],y[mxn];
    char op;
    bool vis[mxn] ;
    int Find(int x) { return x==per[x]?x:per[x] = Find(per[x]); }
    void Union(int u,int v) { per[ Find(u) ] = Find(v); }
    int Dis(int i,int j){return (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ;}
    void solve()
    {
    	while(cin>>n>>m&&(m||n)){
    		for(int i=0;i<=n;i++) per[i] = i ;
    		int u , v , ui , vi ; ans = 1 ;
    		for(int i=1;i<=m;i++){
    			for(cin>>k , _=1;k;k--){
    				cin>>v;
    				if(_==1) { u = v ; _=0 ; ui = Find(u);}
    				else {
    					vi = Find(v) ;
    					if(ui!=vi) per[vi] = ui ;
    				}
    			}
    		}
    		ui = Find(0) ;
    		for(int i=1;i<=n;i++) ans+= (Find(i)==ui);
    		cout<<ans<<endl;
    	}
    }
    int main(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve();return 0;}
    
    
    
    

    How Many Tables

    题意

    求联通块的个数

    题解

    并查集暴搜

    #pragma GCC optimize(2)
    #include <iostream>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    const int inf=0x3f3f3f3f;
    #define eps 1e-5 
    #define pii pair<int,int>
    #define FI first
    #define SE second
    #define ll long long
    #define ull unsigned long long
    const ll mod = 4294967296;/// 998244353;
    const int mxn = 3e4 +7;
    int _ , n , m , t , k ,  cnt , si , res ,ans ;
    template <class T>
    void rd(T &x){
    	T flag = 1 ; x = 0 ; char ch = getchar() ;
    	while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    	while(isdigit(ch)) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
    	x*=flag;
    }
    int to[mxn] , nx[mxn] , head[mxn] ,per[mxn],x[mxn],y[mxn];
    char op;
    bool vis[mxn] ;
    int Find(int x) { return x==per[x]?x:per[x] = Find(per[x]); }
    void Union(int u,int v) { per[ Find(u) ] = Find(v); }
    int Dis(int i,int j){return (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]) ;}
    void solve()
    {
    	for(cin>>t;t;t--){
    		cin>>n>>m; ans = 0 ;
    		for(int i=1;i<=n;i++) per[i] = i ;
    		for(int i=1,u,v;i<=m;i++){
    			cin>>u>>v;
    			int ui = Find(u) , vi = Find(v) ;
    			if(ui!=vi) per[ui] = vi ;
    		}
    		for(int i=1;i<=n;i++) if(per[i]==i) ans++;
    		cout<<ans<<endl;
    	}
    }
    int main(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve();return 0;}
    
    
    

    食物链

    题解

    S:X相对于祖先节点Y的状态,即 0 , 1 , 2 ,表示方法为s[ X,Y ] = root
    per:存储祖先节点
    规定 S[T] = 0 :XY同类
    S[T] = 1 :X捕食Y
    S[T] = 2 :Y捕食X
    初始化,per[x] = x , 那么相对于祖先节点的关系为S[X] = 0
    对于样例来说
    2 1 2 :S[1,1] = 0 , S[2,2] = 0 , S[ 1,2 ] = 2 , 而 per[1] = 1 , per[2] = 2
    那么,per[2] = 1 , S[2,1] = S[1,2] = 1 .
    2 3 3 :S[2,3] = 2 , S[3,per[3] = 3] = s[3,3] = 0 , s[2,per[2]] = s[2,1] = 1 ,而per[2] = 2 , per[3] = 3
    那么,per[3] = 1 , S[3,per[3]] = S[3,1] = S[2,3] - 1 + S[2,1] = 2 - 1 + 1 = 2

    #pragma GCC optimize(2)
    #include <iostream>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    const int inf=0x3f3f3f3f;
    #define eps 1e-5 
    #define pii pair<int,int>
    #define FI first
    #define SE second
    #define ll long long
    #define ull unsigned long long
    const ll mod = 4294967296;/// 998244353;
    const int mxn = 3e5 +7;
    int _ , n , m , t , k ,  cnt , si , res ,ans ;
    template <class T>
    void rd(T &x){
    	T flag = 1 ; x = 0 ; char ch = getchar() ;
    	while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    	while(isdigit(ch)) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
    	x*=flag;
    }
    int per[mxn] , sta[mxn];
    int Find(int x)
    {
    	if(x==per[x]) return x;
    	int top = Find(per[x]) ; sta[x] = ( (sta[ per[x] ]+sta[x])%3); per[x] = top ;
    	return top ;
    }
    void solve()
    {
    	scanf("%d %d",&n,&m);
    	for(int i=0;i<=n;i++) per[i] = i , sta[i] = 0 ; ans = 0 ;
    	for(int i=1,u,v,op;i<=m;i++){
    		scanf("%d %d %d",&op,&u,&v);
    		if(u>n || v>n || (op==2 && u==v)) { ++ans;continue; }
    		int ui = Find(u) , vi = Find(v) ;
    		if(ui==vi && ( (op==1 && sta[u]!=sta[v]) || op==2 && (sta[u]+1)%3!=sta[v]))  ++ans;
    		else per[vi] = ui , sta[vi] = ( -sta[v] + sta[u] + op + 3 - 1)%3; 
    	}
    	printf("%d
    ",ans);
    }
    int main(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve();return 0;}
    

    Parity game

    #pragma GCC optimize(2)
    #include <iostream>
    #include <map>
    #include <vector>
    #include <queue>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    const int inf=0x3f3f3f3f;
    #define eps 1e-5 
    #define pii pair<int,int>
    #define FI first
    #define SE second
    #define ll long long
    #define ull unsigned long long
    const ll mod = 4294967296;/// 998244353;
    const int mxn = 1e5 +7;
    int _ , n , m , t , k ,  cnt , si , res ,ans ;
    template <class T>
    void rd(T &x){
    	T flag = 1 ; x = 0 ; char ch = getchar() ;
    	while(!isdigit(ch)) { if(ch=='-') flag = -1; ch = getchar(); }
    	while(isdigit(ch)) { x = (x<<1) + (x<<3) + (ch^48); ch = getchar(); }
    	x*=flag;
    }
    int per[mxn] , sta[mxn] , uni[mxn] ;
    pair< pii,string > no[mxn];
    int Find(int x){
    	if(x==per[x]) return per[x];
    	int top = Find(per[x]);
    	sta[x]^=sta[per[x]] ;
    	return per[x] = top;
    }
    void solve()
    {
    	int  ans = 0 , cnt = 0 ;
    	string str ;
    	cin>>n>>m;
    	for(int i=1;i<=m;i++) {
    		cin>>no[i].FI.FI>>no[i].FI.SE>>no[i].SE;
    		no[i].FI.FI--;
    		uni[++cnt] = no[i].FI.FI , uni[++cnt] = no[i].FI.SE;
    	}
    	sort(uni+1,uni+1+cnt);
    	int lim = unique(uni+1,uni+1+cnt) - uni - 1 ;
    	for(int i=1;i<=lim;i++) per[i] = i , sta[i] = 0 ;
    	for(int i=1;i<=m;i++){
    		int u = lower_bound( uni+1,uni+1+lim , no[i].FI.FI ) - uni ;
    		int v = lower_bound( uni+1,uni+1+lim , no[i].FI.SE ) - uni ;
    		int ui = Find(u) , vi = Find(v);
    		int bit = no[i].SE[0]=='o'?1 : 0 ;
    		if(ui==vi && sta[u]^bit!=sta[v]) break;
    		if(ui<vi) per[ui] = vi , sta[ui] = sta[v]^bit^sta[u]; 
    		else per[vi] = ui , sta[vi] = sta[u]^bit^sta[v];
    		++ans;
    	}
    	cout<<ans<<endl;
    }
    int main(){ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve();return 0;}
    
    

    暴毙一上午的代码,至此不知道Find替换为下面的代码为什么会WA

    int Find(int x){
    	if(x==per[x]) return per[x];
    	sta[x]^=sta[per[x]] ;
    	return per[x] = Find(per[x]);
    }
    
    所遇皆星河
  • 相关阅读:
    C#
    C#
    C#
    创建一个ROS包
    创建一个工作空间
    ROS的文件系统
    单一职责原因
    策略模式
    UML类图
    简单工厂模式
  • 原文地址:https://www.cnblogs.com/Shallow-dream/p/13795706.html
Copyright © 2020-2023  润新知