分析:
考察并查集,注意中间合并时的时间的合并和人数的合并。
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #include <cstring> 5 #include <string> 6 #include <vector> 7 #include <cctype> 8 #include <map> 9 10 using namespace std; 11 12 const int Max_Int = 0x7fffffff; 13 const int Max_required = 500; 14 15 struct Node //记录gang的信息 16 { 17 int total_person; //gang中总人数 18 int time_length; //gang中总时间 19 int tree; //并查集用处 20 }gang[2005]; 21 22 struct Name 23 { 24 char ch[5]; 25 }; 26 27 map<string, int> Map_Name2int; //名字转下标之用 28 map<int, string> Map_int2Name; 29 int _index; 30 31 int perp[2005]; //记录每个人花的时间 32 33 void Init() 34 { 35 Map_Name2int.clear(); 36 _index = 0; 37 for (int i = 0; i <= 2000; i++) 38 { 39 gang[i].total_person = 1; 40 gang[i].tree = i; 41 gang[i].time_length = 0; 42 perp[i] = 0; 43 } 44 } 45 46 47 int string2index(string name) 48 { 49 map<string, int>::iterator iter = Map_Name2int.find(name); 50 if (iter != Map_Name2int.end()) 51 return iter->second; 52 Map_Name2int.insert(make_pair(name, _index)); 53 Map_int2Name.insert(make_pair(_index, name)); 54 _index++; 55 56 return _index - 1; 57 } 58 59 int get_root(int r) 60 { 61 while (r != gang[r].tree) 62 r = gang[r].tree; 63 return r; 64 } 65 66 //------------------------------------------------- 67 void merge(int fir, int sec, int time) //合并操作。 68 { 69 fir = get_root(fir); 70 sec = get_root(sec); 71 72 if (fir != sec) //如果两个拥有不同的根 73 { 74 gang[sec].tree = fir; 75 gang[fir].time_length += time + gang[sec].time_length; 76 gang[fir].total_person += gang[sec].total_person; 77 } 78 else 79 gang[fir].time_length += time; 80 //cout << gang[fir].total_person << " " << gang[fir].time_length << endl; 81 } 82 83 84 struct Gang //以root为首的群的head,存储答案 85 { 86 int head; 87 int root; 88 string name; 89 }gang_head[1000]; 90 int total_gang; 91 92 void find_head(int k) 93 { 94 total_gang = 0; 95 for (int i = 0; i < _index; i++) 96 { 97 int r = get_root(i); 98 99 //cout << r << " " << Map_int_Name.find(i)->second << endl; 100 101 if (gang[r].total_person > 2 && gang[r].time_length > k) 102 { 103 bool flag = 0; 104 for (int j = 0; j < total_gang; j++) 105 { 106 if (gang_head[j].root == r) 107 { 108 flag = 1; 109 if (perp[gang_head[j].head] < perp[i]) 110 gang_head[j].head = i; 111 break; 112 } 113 } 114 115 if (flag == 0) 116 { 117 gang_head[total_gang].head = i; 118 gang_head[total_gang].root = r; 119 total_gang++; 120 } 121 } 122 } 123 } 124 125 int cmp(const Gang &a, const Gang &b) 126 { 127 return a.name < b.name; 128 } 129 130 void print_info() 131 { 132 for (int i = 0; i < total_gang; i++) 133 gang_head[i].name = Map_int2Name.find(gang_head[i].head)->second; 134 135 sort(gang_head, gang_head + total_gang, cmp); 136 137 printf("%d ", total_gang); 138 for (int i = 0; i < total_gang; i++) 139 { 140 cout << gang_head[i].name << " " << gang[gang_head[i].root].total_person << endl; 141 } 142 143 } 144 145 int main() 146 { 147 int n, k; 148 149 while (scanf("%d%d", &n, &k) != EOF) 150 { 151 152 Init(); //初始化 153 154 string name1, name2; 155 int time; 156 while (n--) 157 { 158 cin >> name1 >> name2 >> time; 159 int fir = string2index(name1); 160 int sec = string2index(name2); 161 162 perp[fir] += time; 163 perp[sec] += time; 164 merge(fir, sec, time); 165 } 166 167 find_head(k); 168 169 print_info(); 170 } 171 return 0; 172 }