牛客 魏迟燕的自走棋
题目链接: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 }

浙公网安备 33010602011771号