题意

有n种科目,每个科目都有一个最高的等级a[i]。开始的时候,每个科目的等级都是0。现在要选择一些课程进行学习使得每一个科目都达到最高等级。这里有m节课可供选择。对于每门课给出L1[i],c[i],L2[i],d[i],money[i],要选择这门课要求科目c[i]的等级不小于L[i],可以使科目d[i]的等级升为L2[i],花费金钱money[i]。请计算最小花费是多少。

数据范围N<=50,M<=2000,sum of a[1] to a[n]不超过500.

分析

最小树形图,要用到朱刘算法。其实。。。我是昨晚在补这道题的时候才去学了一下朱刘算法。。。。。。

朱刘算法学习博客https://blog.csdn.net/txl199106/article/details/62045479

对于这道题我是这么想的,把每个科目的每个等级都拆成点,然后建一个编号为0的点向各个科目等级为0的点连一条权值为0的边。对于每个科目,将他们等级从高到低的点依次连权值为0的点,然后对于每一门课程按照要求连边,权值为这门课程的花费。

建图完成以后,以0点为root跑朱刘算法得到最小树形图,然后这就是答案了。

应该会这个算法就很好做的一道题。

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn=+;
const int INF=; struct Edge{
int from,to;
long long w;
}edges[maxn];
int sz;
int a[],sum[];
int N,M;
void add_edge(int from,int to,long long w){
++sz;
edges[sz].from=from;edges[sz].to=to;edges[sz].w=w;
}
int pre[maxn];//存储父节点
int vis[maxn];//标记作用
int id[maxn];//id[i]记录节点i所在环的编号
int in[maxn];//in[i]记录i入边中最小的权值
long long zhuliu(int root, int n, int m, Edge *edge)//root根 n点数 m边数
{
long long res = ;
int u, v;
while()
{
for(int i = ; i < n; i++)
in[i] = INF;//初始化
for(int i = ; i <= m; i++)
{
Edge E = edge[i];
if(E.from != E.to && E.w < in[E.to])
{
pre[E.to] = E.from;//记录前驱
in[E.to] = E.w;//更新
}
}
for(int i = ; i <n; i++)
if(i != root && in[i] == INF)
return -;//有其他孤立点 则不存在最小树形图
//找有向环
int tn = ;//记录当前查找中 环的总数
memset(id, -, sizeof(id));
memset(vis, -, sizeof(vis));
in[root] = ;//根
for(int i = ; i <n; i++)
{
res += in[i];//累加
v = i;
//找图中的有向环 三种情况会终止while循环
//1,直到出现带有同样标记的点说明成环
//2,节点已经属于其他环
//3,遍历到根
while(vis[v] != i && id[v] == - && v != root)
{
vis[v] = i;//标记
v = pre[v];//一直向上找
}
//因为找到某节点属于其他环 或者 遍历到根 说明当前没有找到有向环
if(v != root && id[v] == -)//必须上述查找已经找到有向环
{
for(int u = pre[v]; u != v; u = pre[u])
id[u] = tn;//记录节点所属的 环编号
id[v] = tn++;//记录节点所属的 环编号 环编号累加
}
}
if(tn == ) break;//不存在有向环
//可能存在独立点
for(int i = ; i <n; i++)
if(id[i] == -)
id[i] = tn++;//环数累加
//对有向环缩点 和SCC缩点很像吧
for(int i = ; i <= m; i++)
{
v = edge[i].to;
edge[i].from = id[edge[i].from];
edge[i].to = id[edge[i].to];
//<u, v>有向边
//两点不在同一个环 u到v的距离为 边权cost - in[v]
if(edge[i].from != edge[i].to)
edge[i].w -= in[v];//更新边权值 继续下一条边的判定
}
n = tn;//以环总数为下次操作的点数 继续执行上述操作 直到没有环
root = id[root];
}
return res;
} int main(){
while(scanf("%d%d",&N,&M)!=EOF&&N&&M){
sz=;
sum[]=;
for(int i=;i<=N;i++){
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i]+;
} int c,L1,d,L2;
long long w;
for(int i=;i<=M;i++){
scanf("%d%d%d%d%lld",&c,&L1,&d,&L2,&w);
/* for(int j=L1;j<=a[c];j++){
add_edge(sum[c-1]+j+1,sum[d-1]+L2+1,w);
}*/
add_edge(sum[c-]+L1+,sum[d-]+L2+,w);
}
for(int i=;i<=N;i++){
add_edge(,sum[i-]+,);
}
for(int i=;i<=N;i++){
for(int j=;j<a[i];j++){
add_edge(sum[i-]+j+,sum[i-]+j+,);
}
}
/*printf("%d\n",sz);
for(int i=1;i<=sz;i++){
printf("%d %d %d\n",edges[i].from,edges[i].to,edges[i].w);
}*/
//cout<<sum[n]<<endl;
long long ans=zhuliu(,sum[N]+,sz,edges);
printf("%lld\n",ans);
}
return ;
}

【HDU4966】GGS-DDU的更多相关文章

  1. 【OGG】OGG基础知识整理

    [OGG]OGG基础知识整理 一.GoldenGate介绍 GoldenGate软件是一种基于日志的结构化数据复制软件.GoldenGate 能够实现大量交易数据的实时捕捉.变换和投递,实现源数据库与 ...

  2. 【OGG】 RAC环境下管理OGG的高可用 (五)

    [OGG] RAC环境下管理OGG的高可用 (五) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道 ...

  3. 【OGG】RAC环境下配置OGG单向同步 (四)

    [OGG]RAC环境下配置OGG单向同步 (四) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的 ...

  4. 【OGG】OGG简单配置双向复制(三)

    [OGG]OGG简单配置双向复制(三) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O ...

  5. 【OGG】OGG的单向复制配置-支持DDL(二)

    [OGG]OGG的单向复制配置-支持DDL(二) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的 ...

  6. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  7. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  8. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  9. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

随机推荐

  1. SBT构建工具

    SBT Simple Build Tool. A interactive build tool. install windows可直接到http://www.scala-sbt.org/0.13/do ...

  2. android知识点大总结

    1.掌握Android编程的基本概念与要点,Android SDK及其开发环境搭建.Android项目结构分析.2.Android 应用设计模式.文件系统.3.文件形式的数据存储与访问.SDCard卡 ...

  3. proxifier 注册码 +电脑全局代理设置

    L6Z8A-XY2J4-BTZ3P-ZZ7DF-A2Q9C(Portable Edition)  5EZ8G-C3WL5-B56YG-SCXM9-6QZAP(Standard Edition)  P4 ...

  4. Android开源框架-Annotation框架(以ViewMapping注解为例)

    Annotation 分类 1 标准 Annotation 包括Override, Deprecated, SuppressWarnings,标准 Annotation 是指 Java 自带的几个 A ...

  5. 无敌JS关闭当前窗口代码,不弹出确认提示

    echo "<script type='text/javascript'>window.opener=null;window.open('','_self');window.cl ...

  6. 字符串长度(PHP学习)

    1.计算字符串长度有哪些方法? 答:strlen()   和  mb_strlen() 2.两者有什么区别 答: 如下代码 <?php $str = 'hello中国'; ?> strle ...

  7. HTTP-POST

    POST方式:用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列中请求URI所指定资源的附加新子项,Post被设计成用统一的方法实现下列功能: 1:对现有资源的解释: 2:向电 ...

  8. 【转】性能测试工具JMeter的使用技巧

    在这此对新版本jmeter的学习+温习的过程,发现了一些以前不知道的功能,所以,整理出来与大分享.本文内容如下. 1.如何使用英文界面的jmeter 2.如何使用镜像服务器 3.Jmeter分布式测试 ...

  9. java代码求奖金。要求从键盘输入利润

    总结:看似文字描述很多, package com.ai; import java.util.Scanner; import com.b.Scaner; //v企业发放的奖金根据利润提成.利润(I)低于 ...

  10. chrome打开新标签页插件

    标签(空格分隔): 日常办公,chrome浏览器 一直被chrome浏览器打开新标签页困扰,每次点开一个新标签页还要再去点一下主页,才能打开搜索页面.如果直接点击主页,又会把当前的页面刷掉,实在是非常 ...