【并查集】:poj1611,The Suspects
2015-12-02 21:35
423 查看
http://poj.org/problem?id=1611
题目大意:
有一个学校,有N个学生,编号为0-N-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,并且这些人如果还参加了别的社团,他所在的社团照样全部感染,求感染的人数。
注意,并查集Find操作:
不进行路径压缩:return Find(a[i].parent)
进行路径压缩:a[i].parent=Find(a[i].parent); return a[i].parent;
不要用while循环!!!
注意下面的错误:
for(i=1;i<=m;i++)
{
cin>>k>>t;
//不应该把这个放到外面,因为在之后的union过程中,t的parent可能会改变
//tp=FindParent(t);
for(j=2;j<=k;j++)
{
cin>>tt;
tp=FindParent(t);
ttp=FindParent(tt);
if(tp!=ttp)
{
Union(tp,ttp);
}
}
}
# include<iostream>
using namespace std;
# define N 30005
struct NODE
{
int p,s;
};
NODE node
;
void MakeSet(int n)
{
for(int i=0;i<=n;i++) //start from "0"
{
node[i].p=i;
node[i].s=1;
}
}
int FindParent(int t)
{
if(t==node[t].p)
{
return t;
}
else
{
int tp=node[t].p;
node[t].p=FindParent(tp);
return node[t].p;
}
}
void Union(int tp, int ttp)
{
if(node[tp].s<node[ttp].s)
{
node[tp].p=ttp;
node[ttp].s+=node[tp].s;
}
else
{
node[ttp].p=tp;
node[tp].s+=node[ttp].s;
}
}
int main()
{
int n,m,k,i,j,t,tt,tp,ttp;
while(true)
{
cin>>n>>m;
if(n==0 && m==0)
{
break;
}
MakeSet(n);
for(i=1;i<=m;i++)
{
cin>>k>>t;
//不应该把这个放到外面,因为在之后的union过程中,t的parent可能会改变
//tp=FindParent(t);
for(j=2;j<=k;j++)
{
cin>>tt;
tp=FindParent(t);
ttp=FindParent(tt);
if(tp!=ttp)
{
Union(tp,ttp);
}
}
}
cout<<node[FindParent(0)].s<<endl;
}
return 0;
}
题目大意:
有一个学校,有N个学生,编号为0-N-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,并且这些人如果还参加了别的社团,他所在的社团照样全部感染,求感染的人数。
注意,并查集Find操作:
不进行路径压缩:return Find(a[i].parent)
进行路径压缩:a[i].parent=Find(a[i].parent); return a[i].parent;
不要用while循环!!!
# include<iostream> using namespace std; # define N 30003 struct STUDENT { int parent; int size; }; STUDENT student ; void MakeUnionFind(int n) { for(int i=0;i<n;i++) { student[i].parent=i; student[i].size=1; } } int FindParent(int i) { /* while(student[i].parent!=i) { student[i].parent=FindParent(student[i].parent); } return student[i].parent; */ if(student[i].parent==i) { return i; } else { //return FindParent(student[i].parent); no path compression //do path compression, 注意,不能使用上面的循环!!! student[i].parent=FindParent(student[i].parent); return student[i].parent; } } void Union(int i, int j) { int ip=FindParent(i); int jp=FindParent(j); if(ip!=jp) { if(student[ip].size<student[jp].size) { student[ip].parent=jp; student[jp].size+=student[ip].size; } else { student[jp].parent=ip; student[ip].size+=student[jp].size; } } } int main() { int n,m,k; int i,j,t1,t2; while(true) { cin>>n>>m; if(n==0 && m==0) { break; } MakeUnionFind(n); for(i=1;i<=m;i++) { cin>>k>>t1; for(j=2;j<=k;j++) { cin>>t2; Union(t1,t2); } } cout<<student[student[0].parent].size<<endl; } return 0; }
注意下面的错误:
for(i=1;i<=m;i++)
{
cin>>k>>t;
//不应该把这个放到外面,因为在之后的union过程中,t的parent可能会改变
//tp=FindParent(t);
for(j=2;j<=k;j++)
{
cin>>tt;
tp=FindParent(t);
ttp=FindParent(tt);
if(tp!=ttp)
{
Union(tp,ttp);
}
}
}
# include<iostream>
using namespace std;
# define N 30005
struct NODE
{
int p,s;
};
NODE node
;
void MakeSet(int n)
{
for(int i=0;i<=n;i++) //start from "0"
{
node[i].p=i;
node[i].s=1;
}
}
int FindParent(int t)
{
if(t==node[t].p)
{
return t;
}
else
{
int tp=node[t].p;
node[t].p=FindParent(tp);
return node[t].p;
}
}
void Union(int tp, int ttp)
{
if(node[tp].s<node[ttp].s)
{
node[tp].p=ttp;
node[ttp].s+=node[tp].s;
}
else
{
node[ttp].p=tp;
node[tp].s+=node[ttp].s;
}
}
int main()
{
int n,m,k,i,j,t,tt,tp,ttp;
while(true)
{
cin>>n>>m;
if(n==0 && m==0)
{
break;
}
MakeSet(n);
for(i=1;i<=m;i++)
{
cin>>k>>t;
//不应该把这个放到外面,因为在之后的union过程中,t的parent可能会改变
//tp=FindParent(t);
for(j=2;j<=k;j++)
{
cin>>tt;
tp=FindParent(t);
ttp=FindParent(tt);
if(tp!=ttp)
{
Union(tp,ttp);
}
}
}
cout<<node[FindParent(0)].s<<endl;
}
return 0;
}
相关文章推荐
- HDU-1213-How Many Tables
- Longest Consecutive Sequence,Distinct Subsequences,Interleaving String,Scramble String
- SARS病毒传染 并查集
- HDU 1213
- CSU1307 并查集+SPFA
- BestWiring——Kruskal算法&并查集
- 1611:The Suspects
- poj3728
- HDU-1233 还是畅通工程(最小生成树&并查集)
- Simon-【深入理解数据结构】有根树的不同实现① —— 并查集
- 家族
- poj 1417 True Liars 解题报告 并查集 DP
- poj 1161
- 并查集——HDOJ 1213How Many Tables解题报告
- 最小生成树——HDOJ 2988 Dark roads解题报告
- HDU 1198 Farm Irrigation(并查集)
- hdu 1213 How Many Tables(并查集,简单题)
- hud 1233 还是畅通工程( kruskal和prim两种方法)
- hdu 1863 畅通工程 (最小生成树kruskal 算法)
- hdu 1213并查集