1139 First Contact (30分)

本文介绍了一种利用C++标准模板库(STL)中的unordered_map和vector实现图论算法的方法,具体展示了如何通过邻接矩阵存储人际关系图,并使用unique和erase函数对重复元素进行高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:

  1. 每一个人名映射到一个整数,用邻接矩阵存储图
  2. 可能会有-0000的情况产生,故用字符串而不是int的方式读入

补充知识:
来源:C++STL中的unique函数解析

unique函数通常和erase函数一起使用,来达到删除重复元素的目的。(注:此处的删除是真正的删除,即从容器中去除重复的元素,容器的长度也发生了变换;而单纯的使用unique函数的话,容器的长度并没有发生变化,只是元素的位置发生了变化)

用法如下:

	vector<int> a ={1,3,3,4,5,6,6,7};
    vector<int>::iterator it_1 = a.begin();
    vector<int>::iterator it_2 = a.end();
    vector<int>::iterator new_end;
 
    new_end = unique(it_1,it_2); //注意unique的返回值为迭代器
    a.erase(new_end,it_2);

通过代码:

#include <iostream>
#include <cstring>
#include <unordered_map>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 310;

int n, m;
unordered_map<string, int> mp;  //从字符串到编号的映射,记录编号
string num[N];  //从编号到字符串的映射,方便输出
int id;  //id初始值默认为0
bool g[N][N];
vector<int> boys, girls;

int main()
{
    cin >> n >> m;
    while (m -- )
    {
        string a, b;
        cin >> a >> b;
        string x = a, y = b;
        if (x.size() == 5) x = x.substr(1);  //取子串:去掉开头的负号
        if (y.size() == 5) y = y.substr(1);
        //判断容器为空:防止重复读入相同字符串
        if (mp.count(x) == 0) mp[x] = ++ id, num[id] = x;
        if (mp.count(y) == 0) mp[y] = ++ id, num[id] = y;
		//建边
        int px = mp[x], py = mp[y];
        g[px][py] = g[py][px] = true;

        if (a[0] != '-') boys.push_back(px);
        else girls.push_back(px);
        if (b[0] != '-') boys.push_back(py);
        else girls.push_back(py);
    }
    //排序,去重
    sort(boys.begin(), boys.end());
    boys.erase(unique(boys.begin(), boys.end()), boys.end());
    sort(girls.begin(), girls.end());
    girls.erase(unique(girls.begin(), girls.end()), girls.end());

    int k;
    cin >> k;

    while (k -- )
    {
        vector<pair<string, string>> res;
        string x, y;
        cin >> x >> y;
		
        vector<int> p = boys, q = boys;
        if (x[0] == '-') p = girls, x = x.substr(1);
        if (y[0] == '-') q = girls, y = y.substr(1);

        int a = mp[x], b = mp[y];

        for (int c : p)
            for (int d : q)
            {
                if (c != a && c != b && d != a && d != b && g[a][c] && g[c][d] && g[d][b])
                    res.push_back({num[c], num[d]});
            }

        sort(res.begin(), res.end());
        cout << res.size() << endl;
        for (auto p : res) cout << p.first << ' ' << p.second << endl;
    }

    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值