[BZOJ2654]tree 最小生成树+贪心

2654: tree

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 2435  Solved: 1011
[Submit][Status][Discuss]

Description

给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。

Input

第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。

Output

一行表示所求生成树的边权和。
V<=50000,E<=100000,所有数据边权为[1,100]中的正整数。

Sample Input

2 2 1
0 1 1 1
0 1 2 0

Sample Output

2

HINT

原数据出错,现已更新 by liutian,但未重测---2016.6.24

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 using namespace std;
 8 int V,E,need,f;
 9 struct data {
10     int u,v,val,c;
11 }e[100005];
12 int fa[50005];
13 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
14 bool cmp(data t,data t1){
15     return t.c==t1.c?t.val<t1.val:t.c<t1.c;
16 }
17 int ans=0;
18 int main() {
19     scanf("%d%d%d",&V,&E,&need);
20     for(int i=1;i<=E;i++) {
21         scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].val,&e[i].c);
22     }
23     sort(e+1,e+E+1,cmp);
24     for(int i=1;i<=V;i++) fa[i]=i;
25     int sum=0;
26     for(int i=1;i<=E;i++) {
27         int x=find(e[i].u),y=find(e[i].v);
28         if(x!=y) {
29             if(sum>=need){
30                 if(e[i].c==0) continue;
31                 sum++;
32                 fa[x]=fa[y];
33                 ans+=e[i].val;
34             }
35             else {
36                 ans+=e[i].val;
37                 fa[x]=fa[y];
38                 sum++;
39             }
40         }
41         if(sum==V-1) break;
42     }
43     printf("%d",ans);
44 }
View Code
O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
原文地址:https://www.cnblogs.com/wls001/p/7718282.html