zoukankan      html  css  js  c++  java
  • HDU 4966:GGS-DDU

    HDU:GGS-DDU

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4966

    题目大意:有$n$个课程,初始都在等级$0$,每个课程需要达到等级$a[i]$.满足$x$课程等级大于等于$dx$时,可花费$w$使得$y$课程等级达到$dy$,求最少需要多少钱?

    最小树形图

    一个有向图若存在从某个点开始的到达所有的的一个最小生成树,则它就是最小树形图。

    引自http://www.cnblogs.com/vongang/archive/2012/07/18/2596851.html

    为每个课程的每个等级设置结点,若$x$课程等级大于等于$dx$时,可花费$w$使得$y$课程等级达到$dy$,则

    建一条从$x$课程等级等于$dx$的点到$y$课程等级等于$dy$的点,长度为$w$的有向边.

    因为课程等级是向下兼容的,即等级高的点可以无消耗达到等级低的点,故每个课程等级高的点向等级低的点建长度为$0$的边.

    从而,求最小代价转化为了求整张图的最小树形图(若某课程达到最高等级那么一定可以达到较低等级).

    求最小树形图的复杂度为$O(VE)$.

    代码如下:

      1 #include <cstdio>
      2 #include <vector>
      3 #include <cstring>
      4 #define N 55
      5 #define MAXN 25055
      6 #define MAXM 30000
      7 using namespace std;
      8 const int inf=10000000;
      9 int n,m,a[N];
     10 struct ZL{
     11     int n,m;
     12     int pre[MAXN],id[MAXN],vis[MAXN];
     13     int inEdge[MAXN];
     14     struct Edge{
     15         int u,v;
     16         int w;
     17     }edge[MAXM];
     18     void init(int n_){
     19         n=n_;m=0;
     20     }
     21     void addedge(int u,int v,int w){
     22         edge[m].u=u;
     23         edge[m].v=v;
     24         edge[m].w=w;
     25         m++;
     26     }
     27     int Directed_MST(int root){
     28         int ans=0,u,v;
     29         while(1){
     30             for(int i=0;i<n;++i)
     31                 inEdge[i]=inf;
     32             for(int i=0;i<m;++i){
     33                 u=edge[i].u;
     34                 v=edge[i].v;
     35                 if(edge[i].w<inEdge[v]&&u!=v) {
     36                     pre[v]=u;
     37                     inEdge[v]=edge[i].w;
     38                 }
     39             }
     40             for(int i=0;i<n;++i)
     41                 if(i!=root&&inEdge[i]==inf)
     42                     return -1;
     43             int cnt=0;
     44             memset(id,-1,sizeof(id));
     45             memset(vis,-1,sizeof(vis));
     46             inEdge[root]=0;
     47             for(int i=0;i<n;++i) {
     48                 ans+=inEdge[i];
     49                 int cur=i;
     50                 while(vis[cur]!=i&&cur!=root&&id[cur]==-1) {
     51                     vis[cur]=i;
     52                     cur=pre[cur];
     53                 }
     54                 if(cur!=root&&id[cur]==-1) {
     55                     v=pre[cur];
     56                     while(v!=cur) {
     57                         id[v]=cnt;
     58                         v=pre[v];
     59                     }
     60                     id[cur]=cnt++;
     61                 }
     62             }
     63             if(cnt==0)
     64                 return ans;
     65             for(int i=0;i<n;++i)
     66                 if(id[i]==-1)
     67                     id[i]=cnt++;
     68             for(int i=0;i<m;++i){
     69                 u=edge[i].u;
     70                 v=edge[i].v;
     71                 edge[i].u=id[u];
     72                 edge[i].v=id[v];
     73                 if(id[u]!=id[v])
     74                     edge[i].w-=inEdge[v];
     75             }
     76             n=cnt;
     77             root=id[root];
     78         }
     79         return ans;
     80     }
     81 }gao;
     82 int main(void){
     83     while(~scanf("%d%d",&n,&m)){
     84         if(n==0&&m==0)break;
     85         a[0]=1;
     86         for(int i=1;i<=n;++i){
     87             scanf("%d",&a[i]);
     88             a[i]+=a[i-1]+1;
     89         }
     90         gao.init(a[n]);
     91         for(int i=1;i<=n;++i){
     92             gao.addedge(0,a[i-1],0);
     93             for(int j=a[i-1];j<a[i]-1;++j)
     94                 gao.addedge(j+1,j,0);
     95         }
     96         for(int i=0;i<m;++i){
     97             int x,dx,y,dy,w;
     98             scanf("%d%d%d%d%d",&x,&dx,&y,&dy,&w);
     99             gao.addedge(a[x-1]+dx,a[y-1]+dy,w);
    100         }
    101         printf("%d
    ",gao.Directed_MST(0));
    102     }
    103 }
  • 相关阅读:
    oracle数据库体系架构详解
    数据库迁移之从oracle 到 MySQL
    一个专业DBA应具备的技能
    Oracle 内存参数调优设置
    正向代理与反向代理的区别
    负载均衡的几种常用方式
    Java虚拟机JVM学习07 类的卸载机制
    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论
    Git 撤销修改
    Git 分支管理和冲突解决
  • 原文地址:https://www.cnblogs.com/barrier/p/6852833.html
Copyright © 2011-2022 走看看