追梦算法网----团队数量

说明

芝加哥组织了一场激烈的军事竞赛,很多国家的军人慕名而来,他们要么是队友,要么是敌人。

现建立如下规则:

我的队友的队友,是我的队友;

我的敌人的敌人也是我的队友;

两个人只要是队友,就认为他们属于同一团队,现给你若干参赛军人之间的关系,请问:最多有多少个团队?

输入格式

第一行是一个整数N(2<=N<=1000),表示参赛的人数(从1编号到N)。 第二行M(1<=M<=5000),表示关于参赛者的关系信息的条数。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是队友,E表示p和q是敌人。输入数据保证不会产生信息的矛盾。

输出格式

输出文件只有一行,表示最大可能的团队数。

样例

输入数据 1

6
4
E 1 4
F 3 5
F 4 6
E 1 2

Copy

输出数据 1

3

Copy

提示

样例结束:[3,5]是一个团队,[4,6]是一个团队,由于1和4、1和2都是敌人,2和4自然成为队友,因此[2,4,6]成为团队,1单独为1个团队,最终有3个团队。

才两三天感觉思路都忘了。。。。😢

这是一道并查集题

反思总结:

1、如果读入是敌人,就记录下来

2、如果读入是队友,直接合并

3、读入数据完成后,将敌人的敌人合并为一个集合

4、最后循环判断集合数即可

注意:

1、因为不知道敌人有多少个,所以使用vector数组存放敌人。

2、在两个两个的合并敌人的时候,注意不要越界,原因就是vector越界出现随机数,而不是 0 (防止越界的方法就是 j+1<b[i].size())

#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define ll long long
int n,m;
char t;
int fa[5007];
vector<int> b[5007];
int vis[5007];
void init() {
    for(int i=1; i<=n; i++) {
        fa[i]=i;
    }
}
int find(int x) {
    int temp=x;
    while(fa[temp]!=temp) {
        temp=fa[temp];
    }
    while(x!=fa[x]) {
        int re=fa[x];
        fa[x]=temp;
        x=re;
    }
    return x;
}
void merge(int x,int y) {
    int u=find(x);
    int v=find(y);
    if(u!=v) {
        fa[u]=v;
    }
}
int main() {
    cin>>n>>m;
    init();
    for(int i=0; i<m; i++) {
        cin>>t;
        if(t=='E') {
            int temp=0;
            cin>>temp;
            int xx;
            cin>>xx;
            b[temp].push_back(xx);
        } else {
            int temp=0,xx=0;
            cin>>temp>>xx;
            merge(temp,xx);
        }
    }
    for(int i=1; i<=n; i++) {
        for(int j=0; j+1<b[i].size(); j++) {//防止越界的方法就是 j+1<b[i].size()
            if(b[i][j]!=0&&b[i][j+1]!=0) {//越界的数值不是0,而是随机的数值
                merge(b[i][j],b[i][j+1]);
            } else
                break;
        }
    }
    int ans=0;
    for(int i=1; i<=n; i++) {
        int temp=find(i);
        if(!vis[temp]) {
            vis[temp]=1;
            ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值