题目
https://pintia.cn/problem-sets/994805342720868352/problems/994805456881434624
题意
给你一个有向图
找出连通图,按条件输出
Sample Input 1:
8 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10
Sample Output 1:
2
AAA 3
GGG 3
思路
比较简单,就是细心读题
- 节点数cnt>2
- 总权sum<K
- head是与他相连的边权总和最大的那个点out_max
- 结果排序输出ss
code(写的有点乱)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map<string,int>id;
map<int,string>st;
struct edge{
int time;
int v;
edge(int x,int y):time(x),v(y){}
};
vector<edge>G[10006];//有向图,便于求sum[]
vector<edge>G1[10006];//无向图,方便求联通
int vis[10006];//访问标记
int flag=0;
int cnt[10006];//计数,每个帮派人数
int sum[10006];//帮派总权重
void DFS(int x)
{
if(vis[x]) return ;
vis[x]=flag;
cnt[flag]++;
for(int i=0;i<G1[x].size();++i) DFS(G1[x][i].v);
}
struct an{
string s;
int n;
}temp;
vector<an>ss;
bool cmp(an x,an y) {return x.s<y.s;}
int main()
{
int N,K; cin>>N>>K;
int num=0;
for(int i=0;i<N;++i)
{
string a,b; int c;
cin>>a>>b>>c;
if(id[a]==0) id[a]=(++num),st[num]=a;
if(id[b]==0) id[b]=(++num),st[num]=b;
G[id[a]].push_back(edge(c,id[b]));
G1[id[a]].push_back(edge(c,id[b]));
G1[id[b]].push_back(edge(c,id[a]));
}
for(int i=1;i<=num;++i)
{
if(vis[i]==0) {
flag++;
DFS(i);
}
}
for(int i=1;i<=num;++i)
{
for(int j=0;j<G[i].size();++j)
{
sum[vis[i]]+=G[i][j].time;
}
}
int ans=0;
for(int i=1;i<=flag;++i)
{
if(cnt[i]>2 && sum[i]>K)
{
ans++;
}
}
cout<<ans<<endl;
for(int i=1;i<=flag;++i)
{
if(cnt[i]>2 && sum[i]>K)
{
int max_out=0,max_id=0;
for(int j=1;j<=num;++j)
{
if(vis[j]==i)
{
int out=0;
for(int k=0;k<G1[j].size();++k)
{
out+=G1[j][k].time;
}
if(out>max_out)
{
max_out=out;
max_id=j;
}
}
}
temp.s=st[max_id];
temp.n=cnt[i];
ss.push_back(temp);
}
}
sort(ss.begin(),ss.end(),cmp);
for(int i=0;i<ss.size();++i)
{
cout<<ss[i].s<<" "<<ss[i].n<<endl;
}
return 0;
}