zoukankan      html  css  js  c++  java
  • 61.新的开始(最小生成树)


    文件名:newstart.cpp

    输入输出文件:newstart.innewstart.out

    时空:50M1s
    【题目描述】
    发展采矿业当然首先得有矿井, FF 花了上次探险获得的千分之一的财富请人在岛
    上挖了 n 口矿井, 但他似乎忘记考虑的矿井供电问题……
    为了保证电力的供应, FF 想到了两种办法:
    1
    在这一口矿井上建立一个发电站, 费用为 v(发电站的输出功率可以供给任
    意多个矿井)。
    2
    将这口矿井与另外的已经有电力供应的矿井之间建立电网, 费用为 p
    FF 希望身为”NewBe_One" 计划首席工程师的你帮他想出一个保证所有矿井电力供
    应的最小花费。
    【输入格式】
    第一行一个整数 n 表示矿井总数。
    2n+1 行,每行一个整数, i 个数 v[i]表示在第 i 口矿井上建立发电站的费用。
    接下来为一个 n*n 的矩阵 P 其中 p[ i , j ]表示在第 i 口矿井和第 j 口矿井之间建立
    电网的费用(数据保证有 p[ i, j ] = p[ j, i ], p[ i, i ]=0
    【输出格式】
    仅一个整数, 表示让所有矿井获得充足电能的最小花费。
    【输入样例】
    4
    5
    4
    NOIP2010 模拟试题
    4
    3
    0 2 2 2
    2 0 3 3
    2 3 0 4
    2 3 4 0
    【输出样例】
    9
    输出样例说明:
    FF 可以选择在4号矿井建立发电站然后把所有矿井都与其建立电网,总花费是
    3+2+2+2 = 9

    【数据范围】
    对于30%的数据:1<=n<=50;
    对于100%的数据:1<=n<=300; 0<=v[i], p[i,j] <=10^5.

    思路:因为不一定仅仅建立一个发电站,那么就建立一个超级源点,把所有点建立发电站的费用设为到这一点的路径,然后在这张图中跑一边kruskal算法就行了 

    代码:

    #include
    using namespace std;
    #include
    #include
    int n;long long sum=0;
    int minfdz=999999,t;//t tiao bian
    struct Edge{
     int u,v,w;
    };
    Edge edge[302*302];
    int fdz[301],father[301];
    int find(int);
    void unionn(int,int);
    int cmp(const Edge &a,const Edge &b)
    {
     return a.w
    }
    void kruskal();
    void input();
    int main()
    {
     freopen("newstart.in","r",stdin);
     freopen("newstart.out","w",stdout);
     input();
     kruskal();
     cout<<sum<<endl;
     fclose(stdin);
     fclose(stdout);
     return 0;
    }
    void kruskal()
    {
     int k=0;
     for(int i=1;i<=n+1;++i)
     father[i]=i;
     sort(edge+1,edge+t+1,cmp);
     for(int i=1;i<=t;++i)
     {
      int r1=find(edge[i].u);
      int r2=find(edge[i].v);
      if(r1!=r2)
      {
       unionn(r1,r2);
       sum+=edge[i].w;
       k++;
       if(k==n) return;
      }
     }
     
    }
    void input()
    {
     scanf("%d",&n);
     t=0;
     for(int i=1;i<=n;++i)
     {
      scanf("%d",&fdz[i]);
      if(fdz[i]
      minfdz=fdz[i];
      edge[++t].u=n+1;
      edge[t].v=i;
      edge[t].w=fdz[i];
      edge[++t].v=n+1;
      edge[t].u=i;
      edge[t].w=fdz[i];
     }
     for(int i=1;i<=n;++i)
       for(int j=1;j<=n;++j)
       {
        edge[++t].u=i;
        edge[t].v=j;
        scanf("%d",&edge[t].w);
       }
    }
    int find(int x)
    {
     if(father[x]!=x) father[x]=find(father[x]);
     return father[x];
    }
    void unionn(int a,int b)
    {
     father[b]=a;
    }

     

  • 相关阅读:
    一分钟制作U盘版BT3
    微软历史最高市值是多少?
    Windows 7系统安装MySQL5.5.21图解
    cocos2d-x3.0 Physics新的物理引擎
    java使用javamail读取邮箱(收件箱为例)
    Java实现第九届蓝桥杯字母阵列
    Java实现第九届蓝桥杯字母阵列
    Java实现第九届蓝桥杯字母阵列
    Java实现第九届蓝桥杯猴子分香蕉
    Java实现第九届蓝桥杯猴子分香蕉
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5370753.html
Copyright © 2011-2022 走看看