zoukankan      html  css  js  c++  java
  • 北方大学多校联合训练第十一场E:Modules

    北方大学多校联合训练第十一场E:Modules

    题目链接:http://112.74.33.53/contest/10/problem/58/

    题目大意:有$1$块主板和$n$个增强模块,增强模块可以加在主板或者其他连在主板上的模块上为其带来$p[i]$的增益,当模块$a[i]$连在模块$b[i]$上时,可以带来额外$q[i]$的增益,问最大增益是多少.

    最小树形图

    不考虑额外增益的情况下,将模块连到模块上的效果与直接连到主板上是一致的,故只需从主板向各个模块连边;考虑额外增益,只需从$b[i]$向$a[i]$额外建边.

    代码如下:

     1 #include <cstdio>
     2 #include <cstring>
     3 #define MAXN 3005
     4 #define MAXM 6005
     5 using namespace std;
     6 typedef long long ll;
     7 const ll inf=1000000000000000;
     8 ll T,n,m,p[MAXN],a,b,q;
     9 struct ZL{
    10     ll n,m;
    11     ll pre[MAXN],id[MAXN],vis[MAXN];
    12     ll inEdge[MAXN];
    13     struct Edge{
    14         ll u,v;
    15         ll w;
    16     }edge[MAXM];
    17     void init(ll n_){
    18         n=n_;m=0;
    19     }
    20     void addedge(ll u,ll v,ll w){
    21         edge[m].u=u;
    22         edge[m].v=v;
    23         edge[m].w=w;
    24         m++;
    25     }
    26     ll Directed_MST(ll root){
    27         ll ans=0,u,v;
    28         while(1){
    29             for(ll i=0;i<n;++i)
    30                 inEdge[i]=inf;
    31             for(ll i=0;i<m;++i){
    32                 u=edge[i].u;
    33                 v=edge[i].v;
    34                 if(edge[i].w<inEdge[v]&&u!=v) {
    35                     pre[v]=u;
    36                     inEdge[v]=edge[i].w;
    37                 }
    38             }
    39             for(ll i=0;i<n;++i)
    40                 if(i!=root&&inEdge[i]==inf)
    41                     return -1;
    42             ll cnt=0;
    43             memset(id,-1,sizeof(id));
    44             memset(vis,-1,sizeof(vis));
    45             inEdge[root]=0;
    46             for(ll i=0;i<n;++i) {
    47                 ans+=inEdge[i];
    48                 ll cur=i;
    49                 while(vis[cur]!=i&&cur!=root&&id[cur]==-1) {
    50                     vis[cur]=i;
    51                     cur=pre[cur];
    52                 }
    53                 if(cur!=root&&id[cur]==-1) {
    54                     v=pre[cur];
    55                     while(v!=cur) {
    56                         id[v]=cnt;
    57                         v=pre[v];
    58                     }
    59                     id[cur]=cnt++;
    60                 }
    61             }
    62             if(cnt==0)return ans;
    63             for(int i=0;i<n;++i)
    64                 if(id[i]==-1)
    65                     id[i]=cnt++;
    66             for(int i=0;i<m;++i) {
    67                 u=edge[i].u;
    68                 v=edge[i].v;
    69                 edge[i].u=id[u];
    70                 edge[i].v=id[v];
    71                 if(id[u]!=id[v])
    72                     edge[i].w-=inEdge[v];
    73             }
    74             n=cnt;
    75             root=id[root];
    76         }
    77         return ans;
    78     }
    79 }gao;
    80 int main(void){
    81     scanf("%lld",&T);
    82     while(T--){
    83         scanf("%lld%lld",&n,&m);
    84         gao.init(n+1);
    85         for(int i=1;i<=n;++i){
    86             scanf("%lld",&p[i]);
    87             gao.addedge(0,i,-p[i]);
    88         }
    89         for(int i=0;i<m;++i){
    90             scanf("%lld%lld%lld",&a,&b,&q);
    91             gao.addedge(b,a,-q-p[a]);
    92         }
    93         printf("%lld
    ",-gao.Directed_MST(0));
    94     }
    95 }
  • 相关阅读:
    本周读书的感想
    程序员应知——学习、思考与分享
    用设计版面的思想编写漂亮的代码
    程序员应知——你有几种武器
    《明星DBA成长之路》读后随想
    有些东西不可替代
    DB2连接串&DB2客户端连接服务端
    数据库连接字符串备忘大全
    ASP Blob类型转存为Long Raw类型
    Oracle read_csv
  • 原文地址:https://www.cnblogs.com/barrier/p/6853313.html
Copyright © 2011-2022 走看看