http://tyvj.cn/p/1602
方法一:拆点
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ms(i,j) memset(i,j, sizeof i);
using namespace std;
int n,m;
int father[2005];
int find(int x)
{
if (father[x]==x) return x;
return father[x] = find(father[x]);
}
int merge(int x, int y)
{
int x1 = find(x);
int y1 = find(y);
if (x1!=y1) father[y1] = x1;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i=1;i<=2*n;i++) father[i] = i;
for (int i=1;i<=m;i++)
{
char ch[10];
int p,q;
scanf("%s %d %d", ch, &p, &q);
char c = ch[0];
if (c=='F')
{
merge(p,q);
} else
{
merge(p, q+n);
merge(q, p+n);
}
}
int ans = 0;
for (int i=1;i<=2*n;i++) find(i);
for (int i=1;i<=n;i++)
if (father[i]==i) ans++;
printf("%d\n", ans);
return 0;
}
方法二:输入如果是朋友就合并,是敌人就邻接表储存起来,然后输入完之后合并所有的敌人,最后统计代表个数即可
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int num[1005], f[1005][1005];
int father[1005];
int n,m;
int find(int i)
{
if (father[i]!=i) father[i] = find(father[i]);
return father[i];
}
int merge(int x, int y)
{
int r1 = find(x);
int r2 = find(y);
father[r2] = r1;
}
int main ()
{
scanf("%d%d%*c", &n, &m);
for (int i=1;i<=n;i++) father[i] = i;
memset(num, 0, sizeof(num));
for (int i=1;i<=m;i++)
{
char c;
int p,q;
c = getchar();
scanf("%d%d%*c", &p, &q);
if (c=='F')
{
merge(p, q);
}
else
{
f[p][++num[p]] = q;
f[q][++num[q]] = p;
}
}
for (int k=1;k<=n;k++)
{
for (int i=1;i<=num[k];i++)
for (int j=1;j<=num[k];j++)
{
merge(f[k][i], f[k][j]);
}
}
for (int i=1;i<=n;i++) find(i);
int ans = 0;
for (int i=1;i<=n;i++)
{
if (father[i]==i) ans++;
}
printf("%d\n", ans);
return 0;
}