题解 | #魏迟燕的自走棋#

九峰与签到题

https://ac.nowcoder.com/acm/contest/9984/A

题目链接:https://ac.nowcoder.com/acm/contest/9984/F

题目大意:给你n个人与m件装备,其中每个人都只能对应配一件装备,每件装备也只能配对应一个人。
每件装备可能对应的人有一个或者两个
同时每件装备具有wi点战斗力
问你最大能获得多少战斗力
思路:
感觉有点类似最大生成树
把每件装备的战斗力都当作边值,人的编号当作点
因为是要最大战斗力那么肯定要排序先最大的边进行合并
利用并查集来合并点,再利用辅助数组v[]判断点是否用过
同时要考虑一下自环的情况(就是每件装备只能对应一个人的时候)
如果这个点没用过就把它选上
AC代码:


#include <iostream>
#include <algorithm>
using namespace std;
struct node{
    int x,y;
    int w;
};
int fa[100010];
int vis[100010];
int findfa(int x){//并查集找根节点
    return fa[x]==x?x:fa[x]=findfa(fa[x]);
 }
 bool cmp(node a,node b){//把边排序
     return a.w>b.w;
 }
 node edge[100010];
 void init(){//并查集初始化
    for(int i=1;i<=100000;i++)fa[i]=i;
 }
int main()
{
    init();
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int k;
        cin>>k;
        if(k==1){//自环的情况
            int x,w;
            cin>>x>>w;
            edge[i].x=x;
            edge[i].y=x;
            edge[i].w=w;
        }else{
           int x,y,w;
           cin>>x>>y>>w;
           edge[i].x=x;
           edge[i].y=y;
           edge[i].w=w;
        }
    }
    sort(edge,edge+m,cmp);
    long long ans=0;
    for(int i=0;i<m;i++){
        int x=findfa(edge[i].x),y=findfa(edge[i].y);
        if(x!=y&&( !vis[x] || !vis[y])){//如果这两个人有一个人没装备就把装备分配给那个人
            ans+=edge[i].w;
            fa[y]=x;
            vis[x]=(vis[x] || vis[y]);//如果两个人都没装备那么他的根节点依然是属于没装备的状态,不然就是有装备的状态
        }else if(x==y&&!vis[x]){//自环,如果该点没用过直接加边
            ans+=edge[i].w;
            vis[x]=1;
        }
    }
    cout<<ans<<endl;
    return 0;
}
全部评论

相关推荐

04-02 10:09
门头沟学院 Java
用微笑面对困难:这里面问题还是很多的,我也不清楚为啥大家会感觉没啥问题。首先就是全栈开发实习9个月的内容都没有java实习生的内容多,1整个技术栈没看出太核心和难点的内容,感觉好像被拉过去打杂了,而且全栈基本上很容易被毙。里面能问的bug是在太多了比如L:继承 BaseMapper 可直接使用内置方法’。请问你的 BaseMapper 是如何扫描实体类注解如果瞬时产生 100 个上传任务,MySQL 的索引设计是否会有瓶颈?你做过分库分表或者索引优化吗?全栈的内容可以针对动态难点去搞,技能特长写在下面吧,你写了这么多技能,项目和实习体现了多少?你可以在项目里多做文章然后把这个放下去,从大致来看实习不算太水,有含金量你也要写上内容针对哨兵里面的节点变化能问出一万个问题,这个很容易就爆了。
提前批简历挂麻了怎么办
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务