题目地址
柳大佬的图+dfs解法
1.hash
2.并查集
3.父节点的维护
4.连通块的计算
ac代码
#include<bits/stdc++.h>
using namespace std;
//离线存储数据
struct Data
{
int id1,id2;
int val;
}data[20000];
//存储每个集合的的数据
struct node
{
int id = 20000; //父节点
int people; //统计该集合节点数
int val;
bool flag = false; //标记集合,用作统计集合个数
}ans[20000];
int fa[20000];
//每个节点的权,用作父节点的维护
int w[20000];
bool vis[20000];
bool cmp(node a,node b)
{
return a.id < b.id;
}
int Find(int x)
{
if(x!=fa[x]) return fa[x] = Find(fa[x]);
return x;
}
void Union(int a,int b)
{
int afa = Find(a);
int bfa = Find(b);
//外层if一定要加!!!
if(afa!=bfa){
if(w[afa]> w[bfa]) fa[bfa] = afa;
else fa[afa] = bfa;
}
}
//应为节点的标记一定是三个字母,可以hash,用26进制表示AAA表示0、AAB表示1
int hashs(string a)
{
int index=0;
for(int i=2;i>=0;i--){
index += (a[i] - 'A') * (int)pow(26,2-i);
}
return index;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<20000;i++)
fa[i] =i;
string a,b;
int w_val;
for(int i=0;i<n;i++){
cin>>a>>b>>w_val;
int ida=hashs(a),idb=hashs(b);
data[i].val = w_val;
data[i].id1 = ida;
data[i].id2 = idb;
w[ida] += w_val;
w[idb] += w_val;
}
for(int i=0;i<n;i++){
vis[data[i].id1] = true;
vis[data[i].id2] = true;
Union(data[i].id1,data[i].id2);
}
//给每块集合的总权赋值,标记集合父节点
for(int i=0;i<n;i++){
int id =Find(data[i].id1);
ans[id].val +=data[i].val;
ans[id].flag = true;
ans[id].id = id;
}
for(int i=0;i<20000;i++){
if(vis[i]){
int id =Find(i);
ans[id].people++;
}
}
sort(ans,ans+20000,cmp);
int cnt=0;
for(int i=0;i<20000;i++){
if(ans[i].flag&&ans[i].people>2&&ans[i].val>k){
cnt++;
}
}
printf("%d\n",cnt);
int i=-1;
while(cnt!=0){
i++;
if(ans[i].flag&&ans[i].people>2&&ans[i].val>k){
string tp="AAA";
int v = ans[i].id;
for(int s=2;s>=0;s--){
int x = v%26;
tp[s] = 'A'+x;
v/=26;
}
cout<<tp<<" "<<ans[i].people<<endl;
cnt --;
}
}
// cout<<w[2109]<<endl;
return 0;
}