bzoj2654

二分答案 给白色的边加上边权使刚刚好取到need条

这个二分是靠有右的。。。。

bzoj2654
 1 #include<bits/stdc++.h>

 2 #define clr(a,x) memset(a,x,sizeof(a))

 3 #define rep(i,l,r) for(int i=l;i<r;i++)

 4 typedef long long ll;

 5 using namespace std;

 6 int read()

 7 {

 8     char c=getchar();

 9     int ans1=0,f=1;

10     while(!isdigit(c)){

11         if(c=='-') f=-1;

12         c=getchar();

13     }

14     while(isdigit(c)){

15         ans1=ans1*10+c-'0';

16         c=getchar();

17     }

18     return ans1*f;

19 }

20 struct edge{

21     int d,v,from,to,p;

22     inline bool operator <(const edge&A)const{

23         return v<A.v||(v==A.v&&p<A.p);

24     }

25 };

26 const int maxn=500005,maxm=100005;

27 edge e[maxm];

28 int f[maxn],n,m,need;

29 int find(int a)

30 {

31     return f[a]==a?f[a]:f[a]=find(f[a]);

32 }

33 int kruskal(int a)

34 {    

35     int cnt=0,ans=0;

36     rep(i,0,n) f[i]=i;

37     rep(i,0,m){

38         if(!e[i].p) e[i].v=e[i].d+a;

39         else e[i].v=e[i].d;

40     }

41     sort(e,e+m);

42     rep(i,0,m){

43         if(find(e[i].from)!=find(e[i].to)){

44             f[find(e[i].from)]=find(e[i].to);

45             if(!e[i].p) cnt++;

46             ans+=e[i].v;

47         }

48     }

49     return cnt>=need?ans:-1;

50 }

51 int erfen(int l,int r)

52 {    

53     if(l==r) return l;

54     int mid=(l+r+1)>>1;

55     int x=kruskal(mid);

56     if(x==-1) return erfen(l,mid-1);

57     return erfen(mid,r);

58 }

59 int main()

60 {

61     n=read(),m=read(),need=read();

62     rep(i,0,m){

63         e[i].from=read(),e[i].to=read(),e[i].d=read(),e[i].p=read();

64     }

65     int k=erfen(-500,500);

66     printf("%d\n",kruskal(k)-need*k);

67     return 0;

68 }
View Code

2654: tree

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 614  Solved: 228
[Submit][Status][Discuss]

Description

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

 

Input

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

 

Output

  一行表示所求生成树的边权和。

 

Sample Input

2 2 1
0 1 1 1
0 1 2 0


Sample Output

2

HINT

 

数据规模和约定

  0:V<=10

  1,2,3:V<=15

  0,..,19:V<=50000,E<=100000

  所有数据边权为[1,100]中的正整数。

 

Source

 
[ Submit][ Status][ Discuss]

你可能感兴趣的:(ZOJ)