zoukankan      html  css  js  c++  java
  • bzoj 4349 最小树形图——朱刘算法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4349.

    学习博客:http://www.cnblogs.com/xzxl/p/7243466.html

    关于这道题,图的边权不是 代价*次数 , 而就是一次的代价,因为只要考虑每个堡垒第一次以什么代价被打,之后都可以用最低代价打它。

    注意 “不需要攻打” 的堡垒。注意重连边的时候把边的端点改成新的标号。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define db double
    using namespace std;
    const int N=55,M=2505; const db INF=1e6;
    int n,b[N];db a[N],mn[N]; bool ok[N];
    namespace DMST{
      int xnt,pre[N],id[N],vis[N]; db in[N];
      struct Ed{
        int x,y; db w;
        Ed(int x=0,int y=0,db w=0):x(x),y(y),w(w) {}
      }ed[M];
      void add(int x,int y,db z){ ed[++xnt]=Ed(x,y,z); }
      db solve(int V,int E)
      {
        db ret=0;
        while(1)
          {
        for(int i=1;i<=V;i++)in[i]=INF,id[i]=vis[i]=0;
        for(int i=1,u,v;i<=E;i++)
          {
            u=ed[i].x; v=ed[i].y;
            if(in[v]>ed[i].w)in[v]=ed[i].w, pre[v]=u;
          }
        for(int i=1;i<=V;i++)
          { if(in[i]==INF)return -1; ret+=in[i];}
        int cnt=0;
        for(int i=1;i<=V;i++)
          {
            vis[i]=i; int cr=pre[i];
            while(cr&&!vis[cr]) vis[cr]=i, cr=pre[cr];
            if(vis[cr]==i)
              {
            id[cr]=++cnt; cr=pre[cr];
            while(!id[cr])id[cr]=cnt, cr=pre[cr];
              }
          }
        if(!cnt)return ret;
        for(int i=1;i<=V;i++)if(!id[i])id[i]=++cnt;
        V=cnt; int tE=E; E=0;
        for(int i=1,u,v;i<=tE;i++)
          {
            u=ed[i].x; v=ed[i].y;
            if(id[u]==id[v])continue;
            ed[++E].x=id[u]; ed[E].y=id[v];//id[]
            ed[E].w=ed[i].w-in[v];
          }
          }
      }
    }
    int main()
    {
      int tn;scanf("%d",&tn);
      for(int i=1;i<=tn;i++)
        {
          scanf("%lf%d",&a[i],&b[i]);
          if(!b[i]){ ok[i]=1;continue;}
          DMST::id[i]=++n; DMST::add(0,DMST::id[i],a[i]);
        }
      int m; db d; scanf("%d",&m);
      for(int i=1,u,v;i<=m;i++)
        {
          scanf("%d%d%lf",&u,&v,&d);
          if(ok[u]||ok[v])continue;
          DMST::add(DMST::id[u],DMST::id[v],d);
          a[v]=min(a[v],d);
        }
      db ans=DMST::solve(n,DMST::xnt);
      for(int i=1;i<=tn;i++)//tn
        if(!ok[i])ans+=(b[i]-1)*a[i];
      printf("%.2f
    ",ans);
      return 0;
    }
  • 相关阅读:
    Flask之threading.loacl方法
    websocket之简易聊天室
    websocket介绍
    Flask之jinja2模板语言
    Flask之基础
    Linux之项目的部署
    Linux之nginx负载均衡
    Linux之nginx
    Linux之redis-cluster
    Linux之redis-sentinel
  • 原文地址:https://www.cnblogs.com/Narh/p/10477978.html
Copyright © 2011-2022 走看看