一道采用并查集的题目,长时间没练习,忘记了权重数组,直接查找更新路径,TLE了几次,发现不对,查查帮助,才明白。除了记录父节点的数组外还有有各节点权值的记录,来优化路径压缩。看来真的生疏了很多,赶快复习复习吧。
Source:
#include
<
iostream
>
using namespace std;
int pers[ 50010 ],wei[ 50010 ];
int i,j,total,m,n,pi,pj;
int main()
{
for ( int cse = 1 ;; ++ cse)
{
scanf( " %d%d " , & n, & m);
if (n == 0 && m == 0 ) break ;
memset(wei, 1 , sizeof (pers));
for (i = 1 ;i <= n; ++ i)pers[i] = i;
for (total = n;m > 0 ; -- m)
{
scanf( " %d%d " , & i, & j);
// search for the root node
for (pi = i;pi != pers[pi];pi = pers[pi]);
// update the search path,shorten it
for (;i != pi;i = pers[i],pers[i] = pi);
for (pj = j;pj != pers[pj];pj = pers[pj]);
for (;j != pj;j = pers[j],pers[j] = pj);
if (pi != pj)
{
if (wei[pi] < wei[pj])
{
pers[pj] = pi;wei[pi] += wei[pj];
} else
{
pers[pi] = pj;wei[pj] += wei[pi];
}
-- total;
}
}
cout << " Case " << cse << " : " << total << endl;
}
return 0 ;
}
using namespace std;
int pers[ 50010 ],wei[ 50010 ];
int i,j,total,m,n,pi,pj;
int main()
{
for ( int cse = 1 ;; ++ cse)
{
scanf( " %d%d " , & n, & m);
if (n == 0 && m == 0 ) break ;
memset(wei, 1 , sizeof (pers));
for (i = 1 ;i <= n; ++ i)pers[i] = i;
for (total = n;m > 0 ; -- m)
{
scanf( " %d%d " , & i, & j);
// search for the root node
for (pi = i;pi != pers[pi];pi = pers[pi]);
// update the search path,shorten it
for (;i != pi;i = pers[i],pers[i] = pi);
for (pj = j;pj != pers[pj];pj = pers[pj]);
for (;j != pj;j = pers[j],pers[j] = pj);
if (pi != pj)
{
if (wei[pi] < wei[pj])
{
pers[pj] = pi;wei[pi] += wei[pj];
} else
{
pers[pi] = pj;wei[pj] += wei[pi];
}
-- total;
}
}
cout << " Case " << cse << " : " << total << endl;
}
return 0 ;
}