PAT甲级 1034 Head of a Gang (30分)

原题链接 PAT甲级 1034 Head of a Gang (30分)


题目大意 假如A和B有通话,就称他们是有关系的。并且A和B之间的权值就是他们通话的时间。一个匪帮被假定为有两个人以上,以及他们之间的权值之和(也就是通话时间之和)超过一个给定的阈值K。在每个匪帮中首领被定义为权值最大的人。现在你需要找出匪帮以及其首领。


分析
1、显然这是道图的问题。匪帮的个数也就是图的连通分量,可以先用DFS求出图的连通分量,判断各个连通分量的顶点个数是否超过2以及权值之和是否超过阈值K。
2、把名字转换为序号,便于构造邻接矩阵以及记录总人数
3、输出要按首领名字字母顺序输出,所以在找到首领和匪帮人数之后先保存在一个vector<node>里面,node是个结构体,保存了首领名字和匪帮人数。然后根据名字对vector排序,输出最终结果。不然会有两个测试点通过不了。

#include<iostream>
#include<map>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
int n, k, t, num=1, cnt=0;
string s1, s2;
map<string, int> sti;
map<int, string> its;
int adj[2002][2002], w[2002];
bool visit[2002] = {false};
vector<int> com[2002];
struct node{
    string name;
    int num;
};
vector<node> ans;
bool cmp(node n1, node n2){
    return n1.name < n2.name;
}
void dfs(int v){
    com[cnt].push_back(v);
    visit[v]=true;
    for(int i=1;i<num;i++){
        if(!visit[i] && adj[v][i]!=0){
            dfs(i);
        }           
    }
}
int strtoid(string s){
    if(sti[s]==0){
        sti[s] = num;
        its[num] = s;
        return num++;
    } 
    return sti[s];      
}
bool isgang(vector<int> v){
    if(v.size()<=2) return false;
    int maxw = 0;
    for(int i=0;i<v.size();i++){
        maxw += w[v[i]];
    }
    if(maxw/2 > k)  return true;
    return false;
}
int main(){
    scanf("%d%d", &n, &k);
    for(int i=0;i<n;i++){
        cin>>s1>>s2;
        int id1 = strtoid(s1);
        int id2 = strtoid(s2);
        scanf("%d", &t);
        adj[id1][id2] = adj[id2][id1] = t;
        w[id1] += t;
        w[id2] += t;
    }
    for(int i=1;i<num;i++){
        if(visit[i]==false){
            dfs(i);
            if(isgang(com[cnt]))
                cnt++;
            else
                com[cnt].clear();
        }
    }
    printf("%d\n", cnt);
    ans.resize(cnt);
    for(int i=0;i<cnt;i++){
        int maxid = com[i][0], nm = com[i].size();
        for(int j=1;j<com[i].size();j++){       
            if(w[maxid] < w[com[i][j]])
                maxid = com[i][j];
        }       
        ans[i] = {its[maxid], nm};
    }
    sort(ans.begin(), ans.end(), cmp);
    for(int i=0;i<cnt;i++){
        cout<<ans[i].name<<" "<<ans[i].num<<endl;
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 我们共享滋养 却无法 共享思想 我的眼睛澄澈 洞见规则 站立着 凝望前行的路标 我们走过建筑 却看不见空间 在数字...
    车前慕阅读 204评论 0 0
  • 当一个人不断懂得去运用种子法则,一切好的事都会发生在你的身上。 我的目标:本月业绩12500,已经完成5400,继...
    生活就该甜甜蜜蜜阅读 234评论 0 0
  • 早就听过《山楂树之恋》,但一直没看,一次偶然在图书馆看到了这本小说,便把我吸引住了,我很想知道里面的故事情节...
    Jenny娟阅读 376评论 0 0

友情链接更多精彩内容