牛客 魏迟燕的自走棋

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

思路:首先对于k=2  每一对人合并成一个集合,表示这个集合内都可以拿起某件装备

对不同的关系都可以合并集合,因为在集合中的任何人都可以拿起 这些装备,通过传递即可

那么再考虑贪心, 对于某件更有价值的装备肯定是要优先拿的,那么并查集维护集合,并且用vis判断集合

内的人是否已经拿满不能够再拿装备了即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define ull unsigned long long
 7 #define pi pair<int,int>
 8 #define fi first
 9 #define sc second
10 #define pb push_back
11 int n,m;
12 int f[maxn];
13 int vis[maxn];
14 
15 struct ac
16 {
17     int u,v,w;
18     bool operator<(ac a)
19     {
20         return w>a.w;
21     }
22 };
23 ac a[maxn];
24 
25 int find1(int x)
26 {
27     if(x==f[x]) return x;
28     return f[x]=find1(f[x]);
29 }
30 
31 
32 
33 int main()
34 {
35     ios::sync_with_stdio(0);
36     cin.tie(0);
37     cin>>n>>m;
38     for(int i=1;i<=n;i++) f[i]=i;
39     for(int i=1;i<=m;i++)
40     {
41         int k;
42         cin>>k;
43         if(k==2)
44         {
45             cin>>a[i].u>>a[i].v>>a[i].w;
46         }
47         else
48         {
49             cin>>a[i].u>>a[i].w;
50             a[i].v=a[i].u;
51         }
52     }
53     sort(a+1,a+1+m);
54     ll ans=0;
55     for(int i=1;i<=m;i++)
56     {
57         int x=a[i].u,y=a[i].v,w=a[i].w;
58         x=find1(x),y=find1(y);
59         if(x!=y)
60         {
61             if(vis[x]&&vis[y]) continue;
62             ans+=w;
63             f[x]=y;
64             vis[y]|=vis[x];
65         }
66         else
67         {
68             if(vis[x]) continue;
69             vis[x]=1;
70             ans+=w;
71         }
72     }
73     cout<<ans<<'\n';
74 
75 
76 
77 
78 
79 }
View Code

 

posted @ 2021-02-24 23:38  canwinfor  阅读(60)  评论(0)    收藏  举报