Disjoint-set title finishing brush

Disjoint-set title finishing brush

Disjoint-set is a data structure, however, for the maintenance and function of its array of rare and extremely versatile, is widely used in very many comprehensive subject,

More classic application is the minimum spanning tree \ (kruskal \) algorithm

T1:Watering Hole G

The meaning of problems

\ (n-\) pastures, need to dig wells, in the \ (I \) digging required number farm \ (W_i \) element, in \ (I \) and \ (J \) water passing between the required number \ ( P_ {i, j} = P_ {j, i} \) yuan, Q. minimum cost.

Ideas:

Obviously this is not the shortest path problem, minimum spanning tree problem is, the purpose is to carry out all farm collusion by the path of least cost

For "dug wells" in the minimum spanning tree somewhat strange operation, in fact, by operating Jianxin point, it can change the initial cost of drilling wells into the distance "to the groundwater well", in order to dig wells in the initial takes into side, a \ (kruskal \)

Code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=305;
int n;
struct Ed{
	int from,to,dis;
};
bool operator<(const Ed &a,const Ed &b){
	return a.dis<b.dis;
}
bool operator>(const Ed &a,const Ed &b){
	return a.dis>b.dis;
}
priority_queue<Ed,vector<Ed>,greater<Ed> > q;
int fa[N];
inline int find(int x){
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
int main(){
	//freopen("P1550_2.in","r",stdin);
	scanf("%d",&n);
	for(int i=0;i<=n;++i) fa[i]=i;
	for(int i=1;i<=n;++i){
		int dis;
		scanf("%d",&dis);
		q.push((Ed){0,i,dis});
	}
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j){
			int dis;
			scanf("%d",&dis);
			if(i!=j)
				q.push((Ed){i,j,dis});
		}
	int ans=0;
	while(!q.empty()){
		Ed u=q.top();
		q.pop();
		int x=u.from,y=u.to;
		if(find(x)==find(y)) continue;
		ans+=u.dis;
		fa[fa[x]]=fa[y];
	}
	printf("%d\n",ans);
	return 0;
}

p.s.

This problem should be noted that during sorted by the right side, it is best with a small heap root, do not use an array of structures + \ (the Sort \) function, because the addition of sinking value of the number of sides is not good grasp, not easy-to-edge sorting, error-prone

T2: students

Meaning of the questions:

\ (A \) and \ (B \) two companies, \ (A \) companies are all male employees, \ (B \) are all female employees, respectively \ (n-\) , \ (m \) th staff ,, respectively \ (the p-\) , \ (q \) relationships within the company, up to ask how much the two companies through a couple of employees dubbed No. 1

Ideas:

This is a bipartite graph looks match, after all, is seeking matching program, but in this strange relationship between the two companies did not, but simply communicate via two No. 1 company, this way, the meaning of the questions conversion, you can clear :

In fact, requires less value in the two companies have a number of employees directly or indirectly related to the number of employees 1

Translation again:

Look at both sides of each run again and set a small number of employees check which company employees with No. 1 of the same collection

Code:

#include<iostream>
#include<cstdio>
using namespace std;
const int N=20005;
int n,m,p,q;
int afa[N],bfa[N];
inline int afind(int x){
	if(afa[x]!=x) afa[x]=afind(afa[x]);
	return afa[x];
}
inline int bfind(int x){
	if(bfa[x]!=x) bfa[x]=bfind(bfa[x]);
	return bfa[x];
}
int main(){
	scanf("%d%d%d%d",&n,&m,&p,&q);
	for(int i=1;i<=n;++i) afa[i]=i;
	for(int i=1;i<=m;++i) bfa[i]=i;
	for(int i=1;i<=p;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		if(afind(x)!=afind(y)) afa[afa[x]]=afa[y];
	}
	for(int i=1;i<=q;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		x=-x;
		y=-y;
		if(bfind(x)!=bfind(y)) bfa[bfa[x]]=bfa[y];
	}
	int jostar=afind(1);
	int dio=bfind(1);
	int a=0,b=0;
	for(int i=1;i<=n;++i)
		if(afind(i)==jostar) ++a;
	for(int i=1;i<=m;++i)
		if(bfind(i)==dio) ++b;
	printf("%d\n",min(a,b));
	return 0;
}

Guess you like

Origin www.cnblogs.com/648-233/p/12628884.html