题意

有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. 从无到有开发自己的Wordpress博客主题---代码环境准备

    注意这里说的是代码环境准备哦,而不是L(M)AMP运行环境哦,运行环境会在后述文章中在写. 一.在本地初始化git环境并且链接上gitee 1.在gitee上创建一个项目托管你的代码 这个不在赘述,按 ...

  2. Oracle 实用技巧

    一.rlwrap 在 linux中使用sqlplus对数据库进行操作,常常由于敲错命令或需要反复执行某条语句,需要像linux本身有的历史回调的功能, rlwrap 可以用来支持oracle下sqlp ...

  3. matlab与modelsim中的文件操作函数

    matlab中 fscanf和fpintf是一对,用fprintf写的必须用fscanf来读. fread和fwrite是一对,用fwrite写的必须用fread来读. 同样的数据,使用fprintf ...

  4. python中的单元测试pyUnit

    python中的单元测试pyUnit   在Python中进行单元测试时需要用到PyUnit模块,Python 2.1及其以后的版本都将PyUnit作为一个标准模块,但如果你使用的是较老版本的Pyth ...

  5. C#网络编程(订立协议和发送文件) - Part.4

    文件传输 前面两篇文章所使用的范例都是传输字符串,有的时候我们可能会想在服务端和客户端之间传递文件.比如,考虑这样一种情况,假如客户端显示了一个菜单,当我们输入S1.S2或S3(S为Send缩写)时, ...

  6. Oracle数据文件和临时文件的管理

    一.数据文件概述在Oracle数据库中,SYSTEM和SYSAUX表空间至少需要包含一个数据文件,此外还将包含多个其他表空间及与其相关的数据文件和临时文件.Oracle的数据文件和临时文件是操作系统文 ...

  7. Android中的基类—抽取出来公共的方法

    在Android中,一般来说一个应用会存在几十个页面,并且一个应用一般也会使用一个特定的主题,其中的页面的风格也是一致的,并且页面中的动画效果.页面的切换效果等也应该保持同样的风格,那么就需要一个基类 ...

  8. junit基础学习

    学习地址一:http://blog.csdn.net/andycpp/article/details/1327147/ 学习地址二:http://blog.csdn.net/zen99t/articl ...

  9. EasyWeChat微信开放平台第三方平台接入

    EasyWeChat微信开放平台第三方平台接入 https://www.cnblogs.com/bainiu/p/8022729.html

  10. 使用阿里云服务器(OOS)实现图片上传

    一: 页面 <%@ page language="java" contentType="text/html; charset=utf-8" pageEnc ...