PAT A1034 并查集或者使用DFS图都可以
题目给定一群人沟通时长,有沟通过的全部算成一组(a和b打,b和c打,a和c一族的),看有几个组大于俩人且权值大于k
首先:并查集
几个需要注意的点
1、输出结果需要是按照字母顺序排序的
2、这个来回都是1000,那么开数组要开到两千,包括father的初始,踩坑了
3、string还是用cin和cout,scanf读出来的在后面会出现奇怪的问题(另外map只能用string不能用char a[])
4、Union的过程加上对weight的判断
5、注意最后输出的是组内人数
6、判断k的是整个组的沟通,个人weight叠加以后需要/2的
#include<stdio.h> #include<iostream> #include<string.h> #include<string> #include<map> #include<algorithm> using namespace std; map<string,int>mp; int father[2005]; int num=0; int weight[2005]; int pd[2005]; int sum[2005]; struct data{ string s1; string s2; }d[2005]; struct ansda{ string s1; int p; }ansdata[2005]; bool cmp(ansda temp1,ansda temp2) { return temp1.s1<temp2.s1; } int getNum(string str) { if(mp.find(str)!=mp.end()) return mp[str]; mp[str]=num; num++; return num-1; } string returnStr(int x) { map<string,int>::iterator it=mp.begin(); while(it->second!=x) it++; return it->first; } int findfather(int x) { int a=x; while(x!=father[x]) { x=father[x]; } while(a!=x) { int z=a; a=father[a]; father[z]=x; } return x; } void Union(int a,int b) { if(findfather(a)!=findfather(b)) { if(weight[findfather(a)]>=weight[findfather(b)]) father[findfather(b)]=findfather(a); else father[findfather(a)]=findfather(b); } } int main() { memset(weight,0,sizeof(weight)); memset(sum,0,sizeof(sum)); int n,k; scanf("%d %d",&n,&k); string s1,s2; int t; for(int i=0;i<=2002;i++) father[i]=i; for(int i=1;i<=n;i++) { char c=getchar(); cin>>d[i].s1>>d[i].s2>>t; weight[getNum(d[i].s1)]+=t; weight[getNum(d[i].s2)]+=t; } for(int i=1;i<=n;i++) Union(getNum(d[i].s1),getNum(d[i].s2)); //printf("num:%d\n",num); memset(pd,0,sizeof(pd)); int ans=0; for(int i=0;i<=num-1;i++) { pd[findfather(i)]++; sum[findfather(i)]+=weight[i]; } /*for(int i=0;i<=num-1;i++) { if(pd[i]>2 && sum[i]/2>k) ans++; }*/ /*for(int i=0;i<=num-1;i++) if(pd[i]>2 && sum[i]/2>k) cout<<returnStr(i)<<" "<<pd[i]<<endl;*/ //int count=0; for(int i=0;i<=num-1;i++) { if(pd[i]>2 && sum[i]/2>k) { ansdata[ans].s1=returnStr(i); ansdata[ans++].p=pd[i]; } } printf("%d\n",ans); sort(ansdata,ansdata+ans,cmp); for(int i=0;i<ans;i++) cout<<ansdata[i].s1<<" "<<ansdata[i].p<<endl; return 0; }View Code
要使用sort
map这里面都是你一个一个按照进入顺序赋值的string键值对,用总num标注的,字符串对应的数字是看你插入的时候对应的num,这里面么有排序。最后结果要排序输出。