• CF444A DZY Loves Physics【结论】


    题目传送门

    话说这道题不分析样例实在是太亏了...结论题啊...

    但是话说回来不知道它是结论题的时候会不会想到猜结论呢...毕竟样例一、二都有些特殊。

    观察样例发现选中的子图都只有一条边。

    于是猜只有一条边的时候解最优。

    飞快地写个暴力,然后和结论对拍,然后假装这个结论是对的,然后就$AC$了(大雾

    还是证明一下这个结论吧:

     用反证法。

    设这样三个点的点权分别为$A$,$B$,$C$,两条边的边权为$n$,$m$

    假设子图中有$A,B,C$三个点比只有两个点更优。

    也就是三个点都选的答案比只选$AB$和只选$BC$都大。

    三个都选的答案:$(A+B+C)/(n+m)$

    只选$AB$:$(A+B)/m$

    只选$BC$:$(B+C)/n$

    则:

    $$(A+B+C)/(n+m)>(A+B)/m$$

    $$(A+B+C)/(n+m)>(B+C)/n$$

    化简:(权都是正数)

    $$(A+B+C)*m>(A+B)*(n+m)$$

    $$(A+B+C)*n>(B+C)*(n+m)$$

    $$↓$$

    $$C*m>A*n+B*n$$

    $$A*n>B*m+C*m$$

    相加:
    $$C*m+A*n>A*n+B*n+B*m+C*m$$

    $0>B*n+B*m$

    由于$B$和$n$,$m$都是正数,导出矛盾。

    所以假设不成立。

    另外,如果$AC$之间有连边的话,那三个都选肯定更不优,分子不变,分母变大了嘛。只选$AC$都不用讨论,至少在这种情况下三个都选干不过只选$AB$或$BC$。

    暴力程序(拿来对拍)

    有同学写的$2^n$枚举子集的暴力,我觉得略麻烦,还是更喜欢自己的(笑)

    甚至还想优化一下自己的暴力,就是在以$1$以外的点为起点的时候,就不把$1$加进去,因为$1$有的状态已经在$1$为起点的算过了。

    但是反正是拿来写对拍嘛,节约考试时间。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<queue>
     5 using namespace std;
     6 #define N 505
     7 #define ll long long
     8 int n,m;
     9 int a[N];
    10 bool vis[N];
    11 double ans=0.0;
    12 vector<pair<int,int> >G[N];
    13 int rd()
    14 {
    15     int f=1,x=0;char c=getchar();
    16     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    17     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    18     return f*x;
    19 }
    20 void dfs(int u,int d,int b)
    21 {
    22     for(int i=0;i<G[u].size();i++)
    23     {
    24         int v=G[u][i].first;
    25         if(vis[v]) continue;
    26         vis[v]=1;
    27         int tmp=0;
    28         for(int j=0;j<G[v].size();j++)
    29             if(vis[G[v][j].first]) tmp+=G[v][j].second;
    30         dfs(v,d+a[v],b+tmp);
    31         vis[v]=0;
    32     }
    33     if(b==0) return ;
    34     ans=max(ans,1.0*d/b);
    35 }
    36 int main()
    37 {
    38     n=rd(),m=rd();
    39     for(int i=1;i<=n;i++)
    40         a[i]=rd();
    41     for(int i=1;i<=m;i++)
    42     {
    43         int u=rd(),v=rd(),w=rd();
    44         G[u].push_back(make_pair(v,w));
    45         G[v].push_back(make_pair(u,w));
    46     }
    47     for(int i=1;i<=n;i++)
    48     {
    49         vis[i]=1;
    50         dfs(i,a[i],0);
    51         vis[i]=0;
    52     }
    53     printf("%.9f
    ",ans);
    54     return 0;
    55 }
    56 //不分析样例真的是个不好的习惯啊 
    Code

    正解程序:(比暴力好写)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<queue>
     5 using namespace std;
     6 #define N 505
     7 #define ll long long
     8 int n,m;
     9 int a[N];
    10 double ans=0.0;
    11 int rd()
    12 {
    13     int f=1,x=0;char c=getchar();
    14     while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    15     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    16     return f*x;
    17 }
    18 int main()
    19 {
    20     n=rd(),m=rd();
    21     for(int i=1;i<=n;i++)
    22         a[i]=rd();
    23     for(int i=1;i<=m;i++)
    24     {
    25         int u=rd(),v=rd(),w=rd();
    26         ans=max(ans,1.0*(a[u]+a[v])/w);
    27     }
    28     printf("%.9f
    ",ans);
    29     return 0;
    30 }
    Code
  • 相关阅读:
    HDU 2121 Ice_cream’s world II 不定根最小树形图
    POJ 3164 Command Network 最小树形图
    POJ 3723 Conscription 最小生成树
    UVA 1175 Ladies' Choice 稳定婚姻问题
    BZOJ 2753 [SCOI2012] 滑雪和时间胶囊 最小生成树
    BZOJ 1854: [Scoi2010]游戏 无向图判环
    HDU 3974 Assign the task 暴力/线段树
    Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路
    uoj 67 新年的毒瘤 割点
    蓝桥
  • 原文地址:https://www.cnblogs.com/lyttt/p/11861148.html
Copyright © 2020-2023  润新知