• hdu4966 最小树形图(最少辅导花费)


    题意:
          以一些科目,和辅导班,每个科目最终要求修到某个等级,可以花一定的钱在辅导班把某一科目修到某一等级,进入辅导班的时候会有一个限制,那就是达到他给出的科目和等级限制,比如a b c d m的意思就是科目a必须达到b等级才可以花m钱把科目c修到d等级,最后问把所有科目修到给定的等级要花的最小辅导费用。

    思路:

          我们可以把每一个科目的每一个等级看成一个点,然后根据给定的关系,把等级和等级之间的边和权建立起来,然后再把非0等级建一条当前等级-1的边,费用为0,意思是修了当前等级,之前的等级也算是修完了,最后在虚拟出来一个点,连接所有等级0的点,意思是最开始0等级的已经修完了,然后一遍最小树形图就行了,对于最小树形图,他其实就是在求有向图的最小生成树,用的是 朱-刘 算法(我自己现在还不了解那个算法,只是直接粘模板而已,自己一直感觉不到这个算法的正确性)。


    #include<stdio.h>
    #include<string.h>
    
    
    //******************************************
    const int maxm=2000000;  //边的个数 
    const int maxn=25100;      //点的个数 
    const int inf=0x3f3f3f3f;
    
    typedef struct 
    {
           int u,v,w;
    }EDGE;
    EDGE e[maxm];
    int pre[maxn],id[maxn],vis[maxn],in[maxn];
    typedef struct 
    { 
       int directedMST(int root ,int n ,int m)  
       {  //从0开始用的 0....N,m条边 
           int res=0,nv=n + 1,i;
           while (1)
           {
               for (i=0;i<nv;i++)
               {
                   in[i]=inf;
               }
               for (i=1;i<=m;i++)
               {
                   int u=e[i].u;
                   int v=e[i].v;
                   if (e[i].w<in[v]&&u!=v)
                   {
                       pre[v]=u;
                       in[v]=e[i].w;
                   }
               }
               for (i=0;i<nv;i++)
               {
                   if (i==root)continue;
                   if (in[i]==inf)return -1;
               }
               int cntnode=0;
               memset(id,-1,sizeof(id[0])*(nv+3));
               memset(vis,-1,sizeof(vis[0])*(nv+3));
               in[root]=0;
               for (i=0;i<nv;i++)
               {
                   res+=in[i];
                   int v=i;
                   while (vis[v]!=i&&id[v]==-1&&v!=root)
                   {
                       vis[v]=i;
                       v=pre[v];
                   }
                   if (v!=root&&id[v]==-1)
                   {
                       for (int u=pre[v];u!=v;u=pre[u])
                       {
                           id[u]=cntnode;
                       }
                       id[v]=cntnode++;
                   }
               }
               if (cntnode==0)break;
               for (i=0;i<nv;i++)
               {
                   if (id[i]==-1)id[i]=cntnode++;
               }
               for (i=1;i<=m;i++)
               {
                   int v=e[i].v;
                   e[i].u=id[e[i].u];
                   e[i].v=id[e[i].v];
                   if (e[i].u!=e[i].v)
                   {
                       e[i].w-=in[v];
                   }
               }
               nv=cntnode;
               root=id[root];
           }
           return res;
       }
    }M_Tree;
    //***************************************
    
    
    int sum[55];
    int num[55];
    
    int main ()
    {
        int n ,m ,i ,j;
        int a ,b ,c ,d ,mo;
        M_Tree T;
        while(~scanf("%d %d" ,&n ,&m) && n + m)
        {
           sum[0] = 0;
           for(i = 1 ;i <= n ;i ++)
           {
              scanf("%d" ,&num[i]);
              num[i] ++;
              sum[i] = sum[i-1] + num[i];
           }
           int tt = 0;
           while(m--)
           {
              scanf("%d %d %d %d %d" ,&a ,&b ,&c ,&d ,&mo);
              b++ ,d ++;
              for(int i = sum[a-1] + b ;i <= sum[a] ;i ++)
              {
                 e[++tt].u = i;
                 e[tt].v = sum[c-1] + d;
                 e[tt].w = mo;
               }
           }
           for(i = 1 ;i <= n ;i ++)
           {
              for(j = sum[i-1] + 2 ;j <= sum[i] ;j ++)
              {
                e[++tt].u = j;
                e[tt].v = j-1;
                e[tt].w = 0;
              }
              e[++tt].u = 0;
              e[tt].v = sum[i-1] + 1;
              e[tt].w = 0;
           }
           printf("%d
    ",T.directedMST(0 ,sum[n] ,tt));   
        }
        return 0;
    }
             
           

  • 相关阅读:
    扩展运算符(Spread operator)
    增强的对象字面量,解构赋值
    ES6 模板字符串(template string)
    let和const
    svg实现放大效果
    svg制作风车旋转
    jquery实现某宝放大点击切换
    jQuery之文档处理
    jQuery之属性操作
    jQuery css操作
  • 原文地址:https://www.cnblogs.com/csnd/p/12062848.html
Copyright © 2020-2023  润新知