备战快速复习--day10

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,这里面么有排序。最后结果要排序输出。

猜你喜欢

转载自www.cnblogs.com/tingxilin/p/12386446.html
今日推荐