题目1446:Head of a Gang
用了并查集,之后遍历统计各组信息,提交之后想到可以在合并集合时就把统计信息顺路做了,这样能少一次遍历,
时间紧迫就不改了。
题目说n小于等于1000,是电话的个数,而不是人的个数,所以并查集要开到2000,没好好读题在这错了测试点。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define MAX 2003
#define NL 6
class People
{
public:
char name[NL];
int tTime;//总通话时间
int father;//用于并查集
void init(char n[NL], int time, int f)
{
for (int i=0; i<NL; i++)
{
name[i] = n[i];
}
tTime = time;
father = f;
}
};
People tree[MAX];//并查集
class Gang
{
public:
int head;//head在tree中的位置
int num;//人数
int time;
Gang()
{
head = -1;
num = 0;
time = 0;
}
void clear()
{
head = -1;
num = 0;
time = 0;
}
bool operator < (Gang g) const
{
if (head == -1)
{
return false;
}
return strcmp(tree[head].name, tree[g.head].name) < 0;
}
};
Gang g[MAX];//团伙
int num;//当前并查集中元素个数
int findPeople(char name[NL])//在并查集中找到name对应people的位置
{
for (int i=0; i<num; i++)
{
if (strcmp(name,tree[i].name) == 0)
{
return i;
}
}
return -1;
}
int findRoot(int t)
{
if (tree[t].father == -1)
{
return t;
}
int tmp = findRoot(tree[t].father);
tree[t].father = tmp;
return tmp;
}
int main()
{
int n, k, i;
while (cin >> n)
{
num = 0;//并查集清空
cin >> k;
for (i=0; i<n; i++)
{
char name1[NL];
char name2[NL];
int time;
cin >> name1>> name2>> time;
//读入people信息
int n1 = findPeople(name1);
int n2 = findPeople(name2);
if (n1 == -1)
{
tree[num].init(name1, time, -1);
n1 = num;//重新定位people在tree中位置
num++;
}
else
{
tree[n1].tTime += time;
}
if (n2 == -1)
{
tree[num].init(name2, time, -1);
n2 = num;
num++;
}
else
{
tree[n2].tTime += time;
}
//合并集合
n1 = findRoot(n1);
n2 = findRoot(n2);
if (n1 != n2)
{
tree[n1].father = n2;
}
}//end of for
for (i=0; i<num; i++)
{
g[i].clear();
}
for (i=0; i<num; i++)
{
int root = findRoot(i);
//第一个结点
if (g[root].head == -1)
{
g[root].head = i;
}
//最长时间为head
if (tree[g[root].head].tTime < tree[i].tTime)
{
g[root].head = i;
}
g[root].time += tree[i].tTime;
g[root].num++;
}
vector<Gang> v;
for (i=0; i<num; i++)
{
if (tree[i].father == -1
&& g[i].num > 2
&& g[i].time > 2*k)
{
v.push_back(g[i]);
}
}
if (!v.empty())
{
sort(v.begin(), v.end());
cout <<v.size() << endl;
for (i=0; i<v.size(); i++)
{
cout << tree[v[i].head].name << " " << v[i].num<< endl;
}
}
else
{
cout << 0 << endl;
}
}//end of while
return 0;
}