Topic links:
https://www.luogu.com.cn/problem/P1330
Reference blog:
https://www.luogu.com.cn/blog/D-fzy/feng-suo-yang-guang-tai-xue
This question himself wrote three explanations, which are different ideas, solutions of this problem with reference to the top blog code, but say it is not clear, then I explain below, is the general understanding
algorithm:
Disjoint-set
Code explanation:
1: f [] array stub node, T [] array in a storage node as a root tree (Unicom component) included in the number of nodes, BJ [] flag for determining whether a last node has been accessed, H [i] denotes the i-nodes in different colors (not in the same tree) node
for(int i=1;i<=m;i++)
{
cin>>a>>b;
int x1=find(a),x2=find(b);
if(x1!=x2)
{
if(h[a])xx(h[a],x2);
if(h[b])xx(h[b],x1);
h[a]=x2;
h[b]=x1;
}
else
{
cout<<"Impossible"<<endl;
return 0;
}
}
2: Note that the same tree node colors (the same strongly connected component a) is the same as
3:
cin>>a>>b;
int x1=find(a),x2=find(b);
if(x1!=x2)
a, b are the same side of the two nodes, then the color of the two nodes can not be the same, i.e., different tree belongs, i.e. different roots, (i.e. components at different intensity Unicom)
4: a different color then the point b and the same color, i.e., with a different color dot H [a] and b roots of X2, the same color, with a number, the analysis Similarly to b
5: h flop memory array point a point, b, Analysis of empathy
if(x1!=x2)
{
if(h[a])xx(h[a],x2);
if(h[b])xx(h[b],x1);
h[a]=x2;
h[b]=x1;
}
6: If they are the same color, not expressed (i.e., with the root a and b, in the same tree, the same color)
else
{
cout<<"Impossible"<<endl;
return 0;
}
7: bj [] for the last mark a node has already been visited
8: it must be clear that this figure is not necessarily Unicom, thus:
for(int i=1;i<=n;i++)
{
int q=find(i);
if(!bj[q])
{
int q1=find(h[i]);
bj[q]=1;
bj[q1]=1;
ans+=min(t[q],t[q1]);
}
}
#include <bits/stdc++.h>
using namespace std;
int f[10001],a,b,n,m,t[10001],bj[10001],h[10001],ans;
void init()
{
for(int i=1;i<=n;i++)
{
f[i]=i;
t[i]=1;
}
}
int find(int x)
{
if(f[x]!=x) f[x]=find(f[x]);
return f[x];
}
void xx(int x,int y)
{
int qq=find(x);
int qq1=find(y);
if(qq!=qq1)
{
f[qq1]=qq;
t[qq]+=t[qq1];
}
}
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
init();
for(int i=1;i<=m;i++)
{
cin>>a>>b;
int x1=find(a),x2=find(b);
if(x1!=x2)
{
if(h[a])xx(h[a],x2);
if(h[b])xx(h[b],x1);
h[a]=x2;
h[b]=x1;
}
else
{
cout<<"Impossible"<<endl;
return 0;
}
}
for(int i=1;i<=n;i++)
{
int q=find(i);
if(!bj[q])
{
int q1=find(h[i]);
bj[q]=1;
bj[q1]=1;
ans+=min(t[q],t[q1]);
}
}
cout <<ans<< endl;
return 0;
}