给N个字符串分组,
第一行输入N(0<N<=100000),接下来N行每行给出两个字符串(0<名字长度<=20),表示该两个字符串为一组
输出最多的组数


最讨厌这种乍一看很简单结果越写越难的题了。。。两种方法的核心都是先判断两个字符串是否已经存在在一个小组内,如果两个在同一个小组,则do nothing;如果在不同的小组,则合并小组;如果只有一个在小组内,则直接把另一个字符串添加进该小组;否则就新建一个小组。

方法一:用vector<set>记录</set>

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int N;
    cin>>N;
    string a,b;
    vector< set<string> > record;
    for(int i=0;i<N;i++){
        cin>>a;
        cin.get();
        cin>>b;
        cin.get();
        //cout<<a<<" "<<b<<endl;
        bool done_flag=false;
        for(int i=0;i<record.size() && !done_flag;i++){
            if(record[i].find(a) != record[i].end() || record[i].find(b) != record[i].end()){
                if(record[i].find(a) != record[i].end() && record[i].find(b) != record[i].end()){
                    done_flag=true;
                    break;
                }
                if(record[i].find(b) != record[i].end()) swap(a,b);
                for(int j=i+1;j<record.size();j++){
                if(record[j].find(b) != record[j].end()){
                        record[i].insert(record[j].begin(),record[j].end());
                        record.erase(record.begin()+ j);
                        done_flag=true;
                        break;
                    }
                }
            }
        }
        if(!done_flag){
            set<string> tmp;
            tmp.insert(a);tmp.insert(b);
            record.push_back(tmp);
        }
    }
    cout<<record.size()<<endl;
    return 0;
}

方法二:链表

#include <bits/stdc++.h>
using namespace std;
/*
定义了一个链表用来存一个组的结点,用set来维护不同的小组
每次得到一对新的字符串,遍历set中每条链表的每个结点
只要其中一个字符串已经存在于某结点:
        继续遍历该链表,如果另一个结点也存在其中,则完成
        如果另一个字符串不在相同链表中,则继续遍历剩下的链表:
            如果在剩下的链表中找到该字符串,则将这条链表移动到第一条链表后面,并删除原来的链表
            如果找不到,则直接将另一个字符串添加到第一条链表后面。
如果两个字符串都不在所有链表中,则新建两个节点,加入set中。
最后set的size就是小组的数量。
*/
struct ListNode{
    string name;
    ListNode* next;
    ListNode* pre;
};
ListNode* nullptr = new ListNode();//可以注释掉,我的编译器不支持c++11
int main()
{
    int N;
    cin>>N;
    string a,b;
    set<ListNode*> record;
    for(int i=0;i<N;i++){
        cin>>a;
        cin.get();
        cin>>b;
        cin.get();
        //cout<<a<<" "<<b<<endl;
        set<ListNode*>::iterator itor;
        int done_flag=-1;//-1表示未完成, 1表示已经完成
        for(itor = record.begin();itor!=record.end() && done_flag==-1 ;itor++){
            ListNode* node = *itor;
            ListNode* tail = nullptr;//记录第一条链表的尾部
            while(node != nullptr && done_flag!=1 ){
                if(node->name==a || node->name==b){//找到其中一个字符串
                        if(node->name == b && done_flag==-1) swap(a,b);//使b为剩下的字符串
                        //这条路径下是否有b节点
                        while(node != nullptr){
                            if(node ->name == b) {
                                done_flag=1;
                                break;
                            }
                            if(node->next == nullptr) tail = node;
                            node = node->next;
                        }
                        if(done_flag==1) break;
                        //这条路径下没有b节点
                        for(itor++; itor!=record.end() && done_flag!= 1;itor++){//继续遍历剩下的链表
                            ListNode* tmp_node = *itor;
                            ListNode* tmp_head = *itor;
                            while(tmp_node != nullptr){
                                if(tmp_node->name == b){//找到了b字符串
                                    tail -> next = tmp_head;
                                    tmp_head->pre = tail;
                                    record.erase(tmp_head);
                                    done_flag = 1;
                                    break;
                                }
                                tmp_node = tmp_node->next;
                            }
                        }
                        if(done_flag != 1){//没有找到b字符串,新建节点添加到a所在链表的尾部
                            ListNode* n = new ListNode();
                            tail->next= n;
                            n->name = b;
                            n->pre = tail;
                            n->next = nullptr;
                            done_flag = 1;
                        }
                }
                node = node->next;
            }
        }
        if(itor == record.end() && (done_flag==-1)){
            ListNode* n1 = new ListNode();
            ListNode* n2 = new ListNode();
            n1->name = a;
            n2->name = b;
            n1->next = n2;
            n1->pre = nullptr;
            n2->pre = n1;
            n2->next = nullptr;
            record.insert(n1);
        }
    }

    cout<<record.size()<<endl;

    return 0;
}