• BZOJ 1232 [Usaco2008Nov]安慰奶牛cheer:最小生成树【树上dfs性质】


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1232

    题意:

      给你一个无向图,n个点,m条边。

      每条边有边权len[i][j],每个点有点权c[i]。

      让你找一棵生成树,并在这棵树上找一个根。

      从根开始dfs整棵树,每经过一条边(或一个点),花费加上对应的边权(点权)。

      问你最小的花费。

    题解:

      树上dfs性质:

        花费 = ∑ (2*len[i][j] + c[i] + c[j]) + c[root]

        (1)每一条边要经过两次。

        (2)每一条边的两个端点会分别被经过一次。

        (3)起点要多经过一次。

      所以加边的时候,边权要设为 2*len[i][j] + c[i] + c[j]。

      跑一遍kruskal,然后给答案加上最小的一个点权。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <algorithm>
      5 #include <vector>
      6 #define MAX_N 10005
      7 #define INF 10000000
      8 
      9 using namespace std;
     10 
     11 struct Edge
     12 {
     13     int sour;
     14     int dest;
     15     int len;
     16     Edge(int _sour,int _dest,int _len)
     17     {
     18         sour=_sour;
     19         dest=_dest;
     20         len=_len;
     21     }
     22     Edge(){}
     23     friend bool operator < (const Edge &a,const Edge &b)
     24     {
     25         return a.len<b.len;
     26     }
     27 };
     28 
     29 int n,m;
     30 int ans;
     31 int c[MAX_N];
     32 int par[MAX_N];
     33 vector<Edge> edge;
     34 
     35 void init_union_find()
     36 {
     37     for(int i=1;i<=n;i++)
     38     {
     39         par[i]=i;
     40     }
     41 }
     42 
     43 int find(int x)
     44 {
     45     return par[x]==x?x:par[x]=find(par[x]);
     46 }
     47 
     48 void unite(int x,int y)
     49 {
     50     int px=find(x);
     51     int py=find(y);
     52     if(px==py) return;
     53     par[px]=py;
     54 }
     55 
     56 bool same(int x,int y)
     57 {
     58     return find(x)==find(y);
     59 }
     60 
     61 int kruskal()
     62 {
     63     init_union_find();
     64     sort(edge.begin(),edge.end());
     65     int cnt=0;
     66     int res=0;
     67     for(int i=0;i<edge.size();i++)
     68     {
     69         Edge temp=edge[i];
     70         if(!same(temp.sour,temp.dest))
     71         {
     72             cnt++;
     73             res+=temp.len;
     74             unite(temp.sour,temp.dest);
     75         }
     76     }
     77     return cnt==n-1?res:-1;
     78 }
     79 
     80 void read()
     81 {
     82     cin>>n>>m;
     83     for(int i=1;i<=n;i++)
     84     {
     85         cin>>c[i];
     86     }
     87     int a,b,v;
     88     for(int i=0;i<m;i++)
     89     {
     90         cin>>a>>b>>v;
     91         edge.push_back(Edge(a,b,2*v+c[a]+c[b]));
     92     }
     93 }
     94 
     95 int find_min()
     96 {
     97     int minn=INF;
     98     for(int i=1;i<=n;i++)
     99     {
    100         minn=min(minn,c[i]);
    101     }
    102     return minn;
    103 }
    104 
    105 void solve()
    106 {
    107     ans=kruskal();
    108     ans+=find_min();
    109 }
    110 
    111 void print()
    112 {
    113     cout<<ans<<endl;
    114 }
    115 
    116 int main()
    117 {
    118     read();
    119     solve();
    120     print();
    121 }
  • 相关阅读:
    关于android4.3 Intel X86 Atom System Image的下载
    dp和px以及sp
    Android项目结构分析
    Performance Testing
    Modifying a Request or Response
    Log Sessions to Local Database
    The Web Sessions List
    Using QuickExec
    AutoResponder Reference
    Fiddler Session标志
  • 原文地址:https://www.cnblogs.com/Leohh/p/7624305.html
Copyright © 2020-2023  润新知