#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;//phone给的是边数没给点数要乘以二(注意)
int visit[2010]={0},numm=0,weight=0,a[2010][2010],head=0,nt=1,w[2010]={0};//numm要条件重置,nt从1开始不能和判断有没有的0冲突
map<string,int> si;
map<int,string> is;
map<string,int> ans;
int stoin(string kp ){
if(si[kp]==0){//不存在给标号
si[kp]=nt;
is[nt]=kp;
nt++;
return si[kp];
}
else{
return si[kp];
}
}
void dfs(int f){//记两个量 nummemeber weight head
visit[f]=1;
numm++;
if(w[f]>w[head]){
head=f;
}
for(int i=1;i<=si.size();i++){
if(a[f][i]!=0){
weight+=a[f][i];//注意本题要将点标记与边标记分开,如果只按点标记会漏掉形成环的一条边的权值
a[f][i]=a[i][f]=0;//标记边(注意)
if(visit[i]==0) //标记点(分开)
dfs(i);
}
}
}
int main(){
int m,k;
string _1,_2;
int _3,_10,_11;
//fill(a[0],a[0]+1010*1010,0);
cin>>m>>k;
for(int i=0;i<m;i++){
cin>>_1>>_2>>_3;
_10=stoin(_1 );//函数圆括号
_11=stoin(_2);
a[_10][_11]+=_3;
a[_11][_10]+=_3;//出问题边权 应合并为一个
w[_10]+=_3;
w[_11]+=_3;
}
for(int i=1;i<=si.size();i++){
if(visit[i]==0){
numm=0;weight=0;head=0;
dfs(i);
if(numm>2&&weight>k){
ans[is[head] ]=numm;
}
}
}
printf("%d\n",ans.size());
for(auto it=ans.begin();it!=ans.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
总结
1.判断连通分量的个数 DFS,遍历一遍所有顶点
2. 当没给顶点只给了边数,让你在输如过程中存储数据时如果只是数字set可以记录个数,如果string 建立键值对两个,并且按他输入的顺序赋值
3.将两个边合成一个权,同时标记边,与标记点分开,如果只按照标记点,当出现环时会出现漏边的情况,所以要分开,边加过去改成0,点只记录该不该向下访问
4.函数圆括号
5.边数没给点数要乘以二,否则会出现段错误(注意)
6. nt从1开始不能和判断有没有的0冲突map中不存在会返回0不能冲突从1开始
7.通货一个函数要哪几个量要明确
英语
问题
dfs写的太慢总结一下各种题型的模板