POJ 2524先用自己的想法做出:
自己的代码:
//POJ 2524
#include<iostream>
#include<fstream>
#include<algorithm>
using namespace std;
int main()
{
// ifstream infile("test.txt");
// if(!infile)
// {
// cout<<"Error"<<endl;
// }
int n,m,i,id[50001],temp,j,tage;
int k1,k2,num=1,num1;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
temp=0;
num1=0;
memset(id,0,sizeof(id));
for(i=0;i<m;i++)
{
cin>>k1>>k2;
if(id[k1]==0&&id[k2]==0)
{
temp++;
num1++;
id[k1]=id[k2]=temp;
}
else if(id[k1]!=0&&id[k2]==0)
{
id[k2]=id[k1];
}
else if(id[k1]==0&&id[k2]!=0)
{
id[k1]=id[k2];
}
else
{
if(id[k1]>id[k2])
{
int big=id[k1];
for(j=1;j<=n;j++)
{
if(id[j]==big)
id[j]=id[k2];
}
num1--;
}
else if(id[k1]<id[k2])
{
int big=id[k2];
for(j=1;j<=n;j++)
{
if(id[j]==big)
id[j]=id[k1];
}
num1--;
}
}
}
for(i=1;i<=n;i++)
{
if(id[i]==0)
num1++;
}
cout<<"Case "<<num++<<": "<<num1<<endl;
}
return 0;
}
2 用查并集的思想
#include<iostream>
#include<fstream>
using namespace std;
int find(int a[],int x)
{
if(a[x]<=0)
return x;
else
return find(a,a[x]);
}
void unio(int a[],int k1,int k2)
{
if(a[k1]<a[k2])
a[k2]=k1;
else
{
if(a[k1]==a[k2])
a[k2]--;
a[k1]=k2;
}
}
int main()
{
// ifstream infile("test.txt");
// if(!infile)
// {
// cout<<"Error"<<endl;
// }
int a[50001],ca=1;
int n,m;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
else
{
int i,k1,k2,rootK1,rootK2;
memset(a,0,sizeof(a));
for(i=0;i<m;i++)
{
cin>>k1>>k2;
rootK1=find(a,k1);
rootK2=find(a,k2);
if(rootK1!=rootK2)
{
unio(a,rootK1,rootK2);
}
}
int num=0;
for(i=1;i<=n;i++)
{
if(a[i]<=0)
num++;
}
cout<<"Case "<<ca<<": "<<num<<endl;
ca++;
}
}
return 0;
}
错误总结:
1 当只有输入为两个0才停止,注意输入中有一个0的边界情况。
2 在对数据赋值时千万注意,不要把其值已改变的值,并把其当成原值再去赋给其它的值,这样错误很隐蔽。