zoukankan      html  css  js  c++  java
  • SDOJ 3696 Tree

    描述

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

    输入

    第一行V,E,need分别表示点数,边数和需要的白色边数。

    接下来E行

    每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)

    输出

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

    样例输入

    2 2 1
    0 1 1 1
    0 1 2 0

    样例输出

    2

    数据规模和约定

    0%:V<=10

    30%:V<=15

    100%:V<=50000,E<=100000

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

    .......................

    太困了!!!!!!

    先贴个代码 明天再写思路

    耶~

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #define N 50010
     7 using namespace std;
     8 int n,m,k;
     9 int first[N],cnt;
    10 int a[N*2],b[N*2],c[N*2],d[N*2];
    11 int fa[N],sum;
    12 struct node
    13 {
    14     int u,v,w,nxt;
    15     int col;
    16 }e[N*2];
    17 void ade(int x,int y,int z,int c,int i)
    18 {
    19     e[i].u=x;
    20     e[i].v=y;
    21     e[i].w=z;
    22     e[i].col=c;
    23 }
    24 bool cmp(const node &p,const node &q)
    25 {
    26     if(p.w!=q.w)
    27           return p.w<q.w;
    28     return p.col<q.col;
    29 }
    30 int la(int x)
    31 {
    32     if(fa[x]!=x) fa[x]=la(fa[x]);
    33     return fa[x];
    34 }
    35 bool kruskal(int x)
    36 {
    37     for(int i=0;i<n;i++) fa[i]=i;
    38     for(int i=1;i<=m;i++)
    39     {
    40         ade(a[i],b[i],c[i],d[i],i);
    41         if(d[i]==0) e[i].w+=x;
    42     }
    43     sort(e+1,e+m+1,cmp);
    44     sum=0;
    45     int num=0,ans=0;
    46     for(int i=1;i<=m;++i)
    47     {
    48         if(la(e[i].u)!=la(e[i].v))
    49         {
    50             num++;
    51             sum+=e[i].w;
    52             fa[la(e[i].u)]=la(e[i].v);
    53             if(e[i].col==0) ans++;
    54         }
    55         if(num==n-1) break;
    56     }
    57     if(ans>=k)
    58         return true;
    59     return false;
    60 }
    61 int main()
    62 {
    63     scanf("%d%d%d",&n,&m,&k);
    64     for(int i=1;i<=m;i++)
    65         scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
    66     int l=-100,r=100,mid;
    67     while(l<r)
    68     {
    69         mid=(l+r+1)>>1;
    70         if(kruskal(mid)) l=mid;
    71         else r=mid-1;
    72     }
    73     kruskal(l);
    74     printf("%d",sum-k*l);
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    网络编程的基础
    day31作业
    异常处理其他内容
    异常处理的使用
    常见的异常种类
    ansible条件使用--实践
    Ansible的循环
    Ansible的条件语句
    ansibleplaybook的使用
    ansible官方文档翻译之变量
  • 原文地址:https://www.cnblogs.com/kylara/p/9440303.html
Copyright © 2011-2022 走看看