n个技能,每个技能有0~a[i]的等级,m个课程,每个课程需要前置技能c[i]至少达到lv1[i]等级,效果是技能d[i]达到lv2[i]等级,花费w[i]。

输出最小花费使得全技能满级(初始全技能0等级)

n<=50,Σa[i]<=500,m<=2000

点<=551,边<=2000+50+Σ((a[i]+1)*a[i]/2)

Σw[i]<=2000*1000<0x3f3f3f3f

比赛时候完全不在状态,什么题都想不到,坑队友了。。。

最小树形图~做过tarjan缩点的问题应该不大~以前做过不过好像没留下代码现在留下~

攻略步骤:

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

引用http://blog.csdn.net/wsniyufang/article/details/6747392

1、找到除了root以为其他点的权值最小的入边。用In[i]记录

2、如果出现除了root以为存在其他孤立的点,则不存在最小树形图。

3、找到图中所有的环,并对环进行缩点,重新编号。
4、更新其他点到环上的点的距离,如:

环中的点有(Vk1,Vk2,… ,Vki)总共i个,用缩成的点叫Vk替代,则在压缩后的图中,其他所有不在环中点v到Vk的距离定义如下:
gh[v][Vk]=min { gh[v][Vkj]-mincost[Vkj] } (1<=j<=i)

而Vk到v的距离为
gh[Vk][v]=min { gh[Vkj][v] }              (1<=j<=i)

5、重复3,4知道没有环为止。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std; #define inf 0x3f3f3f3f
#define maxn 566
#define maxm (566*566+2000) struct Edge{
int u,v,w;
}e[maxm];
int in[maxn], pre[maxn];
int vis[maxn];
int belong[maxn];
int solve(int root,int n,int esz){// 1-based
int ret=0;
while(1){
for(int i=1;i<=n;++i) in[i]=inf;
for(int i=1;i<=esz;++i){// 找最小边
int u=e[i].u, v=e[i].v, w=e[i].w;
if(v==u){
swap(e[i--],e[esz--]);
continue;
}
if(w<in[v])
in[v]=w, pre[v]=u;
}
for(int i=1;i<=n;++i) if(in[i]==inf && i!=root) return inf;// 无解
int cnt=0;
memset(belong,-1,sizeof(belong));
memset(vis,-1,sizeof(vis));
in[root]=0;
for(int i=1;i<=n;++i){// 找环
ret+=in[i];
int v = i;
while(vis[v]!=i && belong[v]==-1 && v!=root)
vis[v] = i, v = pre[v];
if(vis[v]==i){// 有环,重新编号
belong[v]=++cnt;
for(int u=pre[v];u!=v;u=pre[u])
belong[u]=cnt;
}
}
if(cnt==0) break;// 已成型
for(int i=1;i<=n;++i) if(belong[i]==-1) belong[i]=++cnt;// 不在环内,重新编号
for(int i=1;i<=esz;++i){// 更新环外点和环缩点后的点的距离
int v=e[i].v;
e[i].u=belong[e[i].u];
e[i].v=belong[e[i].v];
if(e[i].u!=e[i].v) e[i].w-=in[v];
}
n=cnt;
root=belong[root];
}
return ret;
}
int main(){
int n,m;
int a[55],s[55];
while(~scanf("%d%d",&n,&m) && n+m){
s[0]=1;
for(int i=1;i<=n;++i) scanf("%d",a+i), s[i]=s[i-1]+a[i]+1;
int esz=0;
for(int i=0;i<m;++i){
int c,l1,d,l2,w;
scanf("%d%d%d%d%d",&c,&l1,&d,&l2,&w);
int u=s[c-1]+l1+1, v=s[d-1]+l2+1;
++esz;
e[esz].u=u,e[esz].v=v,e[esz].w=w;
}
for(int i=1;i<=n;++i){
++esz;
e[esz].u=1,e[esz].v=s[i-1]+1,e[esz].w=0;
for(int j=0;j<=a[i];++j){
for(int k=0;k<j;++k){
int u=s[i-1]+j+1,v=s[i-1]+k+1;
++esz;
e[esz].u=u,e[esz].v=v,e[esz].w=0;
}
}
}
int ans=solve(1,s[n],esz);
if(ans==inf) puts("-1");
else printf("%d\n",ans);
}
return 0;
}

HDU 4966 GGS-DDU(最小树形图)的更多相关文章

  1. HDU 4009 Transfer water 最小树形图

    分析:建一个远点,往每个点连建井的价值(单向边),其它输水线按照题意建单向边 然后以源点为根的权值最小的有向树就是答案,套最小树形图模板 #include <iostream> #incl ...

  2. hdu 2121 , hdu 4009 无定根最小树形图

    hdu 2121 题目:给出m条有向路,根不确定,求一棵最小的有向生成树. 分析:增加一个虚拟节点,连向n个节点,费用为inf(至少比sigma(cost_edge)大).以该虚拟节点为根求一遍最小树 ...

  3. hdu 2121无根最小树形图要建一个虚拟节点

    #include<stdio.h> #include<string.h> #define inf 999999999 #define N 1100 struct node { ...

  4. hdu 4966 GGS-DDU (最小树形图)

    比较好的讲解:http://blog.csdn.net/wsniyufang/article/details/6747392 view code//首先为除根之外的每个点选定一条入边,这条入边一定要是 ...

  5. HDU 2121 Ice_cream’s world II 最小树形图 模板

    开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...

  6. HDU 6141 I am your Father!(最小树形图+权值编码)

    http://acm.hdu.edu.cn/showproblem.php?pid=6141 题意: 求最大树形图. 思路: 把边的权值变为负值,那么这就是个最小树形图了,直接套模板就可以解决. 有个 ...

  7. HDU 6141 I am your Father!(最小树形图)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6141 [题目大意] 给出一个有向图,求1点为根的最小树形图使得第n个点的直接父亲编号最小 [题解] ...

  8. HDU 2121——Ice_cream’s world II——————【最小树形图、不定根】

    Ice_cream’s world II Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  9. hdu 2121 Ice_cream’s world II (无定根最小树形图)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目大意: 有n个点,有m条单向路,问这n个点组成最小树形图的最小花费. 解题思路: 1:构造 ...

随机推荐

  1. centos 安装 mysql5.6

    转载自 http://www.cnblogs.com/littlehb/archive/2013/04/02/2995007.html Mysql 5.5以后使用了CMake进行安装,参考与以前的区别 ...

  2. Java反射机制(Reflection)

    Java反射机制(Reflection) 一.反射机制是什么 Java反射机制是程序在运行过程中,对于任意一个类都能够知道这个类的所有属性和方法;对于任意一个对象都能够调用它的任意一个方法和属性,这种 ...

  3. thinkphp 完整配置config.php

    ThinkPHP的系统配置都采用数组形式,配置文件地址:Bin/Conf/config.php CHECK_FILE_CASE -- windows环境下面的严格检查大小写.     /* 项目设定 ...

  4. Pattern Recognition and Machine Learning (preface translation)

    前言 鉴于机器学习产生自计算机科学,模式识别却起源于工程学.然而,这些活动能被看做同一个领域的两个方面,并且他们同时在这过去的十年间经历了本质上的发展.特别是,当图像模型已经作为一个用来描述和应用概率 ...

  5. PHP 数组的遍历的几种方式(以及foreach与for/while+each效率的比较)

    * 使用foreach遍历数组时要注意的问题: * 1.foreach在遍历之前会自动重置指针使用其指向第一个元素,所以foreach可以多次遍历 * 2.foreach遍历完成之后,指针是没有指向数 ...

  6. HDOJ 4751 Divide Groups

    染色判断二分图+补图 比赛的时候题意居然是反的,看了半天样例都看不懂 .... Divide Groups Time Limit: 2000/1000 MS (Java/Others)    Memo ...

  7. HDOJ 4739 Zhuge Liang&#39;s Mines

    Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. HTTPS科普扫盲帖 对称加密 非对称加密

    http://www.cnblogs.com/chyingp/p/https-introduction.html

  9. 深入理解Java虚拟机之读书笔记一 自动内存管理机制

    一.运行时数据区域 1.程序计数器是线程的私有空间,每个线程都有.针对线程执行的是Java代码还是Native代码有两种取值,Java代码时:虚拟机字节码指令的地址:Native代码时:计数值为Und ...

  10. BZOJ1030——文本生成器

    给你若干给字符串,再给你一个m,问长度是m的字符串中包含给定字符串的数量mod 10007是多少 这个拿过来啥思路也没有,后来还是看了题解,才知道,原来,原来....那个带fail的Trie还可以搞别 ...