GGS-DDU

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 318    Accepted Submission(s): 166
Problem Description
Do you think this is a strange problem name? That is because you don't know its full name---'Good Good Study and Day Day Up!". Very famous sentence! Isn't it?



Now "GGS-DDU" is lzqxh's target! He has N courses and every course is divided into a plurality of levels. Just like College English have Level 4 and Level 6.



To simplify the problem, we suppose that the i-th course has Levels from level 0 to level a[i]. And at the beginning, lzqxh is at Level 0 of every course. Because his target is "GGS-DDU", lzqxh wants to reach the highest Level of every course.




Fortunately, there are M tutorial classes. The i-th tutoial class requires that students must reach at least Level L1[i] of course c[i] before class begins. And after finishing the i-th tutorial class, the students will reach Level L2[i] of course d[i]. The
i-th tutoial class costs lzqxh money[i].



For example, there is a tutorial class only students who reach at least Level 5 of "Tiyu" can apply. And after finishing this class, the student's "MeiShu" will reach Level 10 if his "MeiShu"'s Level is lower than 10. (Don't ask me why! Supernatural class!!!")



Now you task is to help lzqxh to compute the minimum cost!
 
Input
The input contains multiple test cases.



The first line of each case consists of two integers, N (N<=50) and M (M<=2000).

The following line contains N integers, representing a[1] to a[N]. The sum of a[1] to a[N] will not exceed 500.


The next M lines, each have five integers, indicating c[i], L1[i], d[i], L2[i] and money[i] (1<=c[i], d[i]<=N, 0<=L1[i]<=a[c[i]], 0<=L2[i]<=a[d[i]], money[i]<=1000) for the i-th tutorial class. The courses are numbered from 1 to N.



The input is terminated by N = M = 0.
 
Output
Output the minimum cost for achieving lzqxh's target in a line. If his target can't be achieved, just output -1.
 
Sample Input
3 4
3 3 1
1 0 2 3 10
2 1 1 2 10
1 2 3 1 10
3 1 1 3 10
0 0
 
Sample Output
40
题意:有n门课程,每个课程有0到a[i]的等级划分;现在有m个选修课,第i个选修课需要第c[i]的课程至少达到L1[i]的等级,修完后能让第d[i]个课程达到
L2[i]的等级,问至少花费多少可以让每个课程都达到最高水平,如果不能实现目标输出-1;
官方题解:
把每门课的每个等级看作是一个节点,对于没门课程,第j个等级向第j-1个等级连一条边,费用为0,对于第i个选修课,如果每个class需要class11的等级至少L1,修完后可使class12的等级到达L2,则把class11到class12连一条边费用是money[i];每门课的0等级合并作为根节点,这样就转化为以根节点出发到达其他节点的最小费用,此时就是最小树形图了;
#include"string.h"
#include"stdio.h"
#include"math.h"
#include"queue"
#define eps 1e-10
#define M 26000
#define inf 100000000
using namespace std;
struct node
{
int x,y,z;
}p[M];
struct Edge
{
int u,v;
int w;
}edge[30000];
int pre[M],id[M],use[M],in[M],a[M],s[M];
int Fabs(int x)
{
return x>0?x:-x;
}
void add(int u,int v,int w,int m)
{
edge[m].u=u;
edge[m].v=v;
edge[m].w=w;
}
int mini_tree(int root,int n,int m)//分别是树根,节点数,边数,序号从1开始
{
int ans=0;
int i,u;
while(1)
{
for(i=1;i<=n;i++)
in[i]=inf;
for(i=1;i<=m;i++)
{
int u=edge[i].u;
int v=edge[i].v;
if(edge[i].w<in[v]&&u!=v)
{
in[v]=edge[i].w;
pre[v]=u;
}
}//找最小的入边
for(i=1;i<=n;i++)
{
if(i==root)continue;
ans+=in[i];//把边权加起来
if(in[i]==inf)//如果存在没有入弧的点则不存在最小树形图
return -1;
}
memset(id,-1,sizeof(id));
memset(use,-1,sizeof(use));
int cnt=0;
for(i=1;i<=n;i++)//枚举每个点,搜索找环
{
int v=i;
while(v!=root&&use[v]!=i&&id[v]==-1)
{
use[v]=i;
v=pre[v];
}
if(v!=root&&id[v]==-1)//当找到环的时候缩点编号
{
++cnt;
id[v]=cnt;
for(u=pre[v];u!=v;u=pre[u])
id[u]=cnt;
}
}
if(cnt==0)//如果没有环结束程序
break;
for(i=1;i<=n;i++)//把余下的不在环里的点编号
if(id[i]==-1)
id[i]=++cnt;
for(i=1;i<=m;i++)//建立新的图
{
int u=edge[i].u;
int v=edge[i].v;
edge[i].u=id[u];
edge[i].v=id[v];
if(edge[i].u!=edge[i].v)
edge[i].w-=in[v];
}
n=cnt;//更新节点数和根节点的编号
root=id[root];
}
return ans;
}
int main()
{
int n,m,i,j,c,d,L1,L2,money;
while(scanf("%d%d",&n,&m),m||n)
{
s[0]=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s[i]=s[i-1]+a[i];
}
int E=0;
int root=s[n]+1;
int V=s[n]+1;
for(i=1;i<=n;i++)
{
for(j=s[i-1]+2;j<=s[i];j++)
add(j,j-1,0,++E);
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d%d",&c,&L1,&d,&L2,&money);
int u,v;
if(L1==0)
u=root;
else
u=s[c-1]+L1;
if(L2==0)
v=root;
else
v=s[d-1]+L2;
if(u!=v)
add(u,v,money,++E);
}
int ans=mini_tree(root,V,E);
printf("%d\n",ans);
}
return 0;
}

最小树形图(hdu4966多校联赛9)的更多相关文章

  1. HDU4966 GGS-DDU(最小树形图)

    之前几天想着补些算法的知识,学了一下最小树形图的朱刘算法,不是特别理解,备了份模板以备不时之需,想不到多校冷不丁的出了个最小树形图,没看出来只能表示对算法不太理解吧,用模板写了一下,然后就过了.- - ...

  2. hdu4966 最小树形图+虚根

    /* 辛辛苦苦调试半天, 过了样例,竟然没有ac!! 网上对比了ac代码,感觉添加一个虚根就能ac 但是想不明白为什么 */ /* 第二天想了下,知道了为什么wa:因为从等级0连到其他课程等级i的不止 ...

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

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

  4. bzoj4349: 最小树形图

    最小树形图模板题…… 这种\(O(nm)\)的东西真的能考到么…… #include <bits/stdc++.h> #define N 60 #define INF 1000000000 ...

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

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

  6. HDU 4966 GGS-DDU(最小树形图)

    n个技能,每个技能有0-a[i]的等级,m个课程,每个课程需要前置技能c[i]至少达到lv1[i]等级,效果是技能d[i]达到lv2[i]等级,花费w[i]. 输出最小花费使得全技能满级(初始全技能0 ...

  7. hdu3072 强连通+最小树形图

    题意:有一个人他要把一个消息通知到所有人,已知一些通知关系:A 能通知 B,需要花费 v,而又知道,如果某一个小团体,其中的成员相互都能直接或间接通知到,那么他们之间的消息传递是不需要花费的,现在问这 ...

  8. POJ3164 Command Network(最小树形图)

    图论填个小坑.以前就一直在想,无向图有最小生成树,那么有向图是不是也有最小生成树呢,想不到还真的有,叫做最小树形图,网上的介绍有很多,感觉下面这个博客介绍的靠谱点: http://www.cnblog ...

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

    [解题思路]这题先看了NotOnlySuccess的解题思路,即设置虚根再处理的做法:弄了一个上午,再次有种赶脚的感觉~~如果需要找出为什么需要去比所有权值之和更大的数为新增的虚边的话,一开始我理解仅 ...

随机推荐

  1. 事件总线demo

    经过几天的努力拜读大牛高手文章,终于对事件总线有所了解,特此记录下来,以免忘记 1.定义相关的接口: A  事件接口 public interface IDomainEvent { DateTime ...

  2. android EditText设置光标、边框和图标,以及限制输入

    控制边框形状,先在drawable中建一个xml文件:shape.xml <?xml version="1.0" encoding="utf-8"?> ...

  3. 关于Unity中的删除、显示和隐藏节点

    一.删除节点和组件 1.删除一个节点,以及节点上面所有的组件全部删除了//删除一个节点的时候,节点上面所有的组件也会被删除:MonoBehaviour.Destroy(this.gameObject) ...

  4. 关于Cocos2d-x中数据的存储提取和类型转换

    1.获得存储在UserDefault中的变量,但是获得的变量是一个String类型的值,要用atoi函数转换为整型,但是atoi函数的传递参数是一个char*类型的值,所以用_Score.c_str( ...

  5. selenium测试(Java)-- 键盘事件(七)

    1 package com.test.key; 2 3 import org.openqa.selenium.By; 4 import org.openqa.selenium.Keys; 5 impo ...

  6. (转)基于live555的流媒体代理转发服务器

    对于并发量并不大而且对性能要求不是很高的流媒体传输模块,live555还是很好的选择,下面说一下我所实现的流媒体代理服务器(目前只能实现对H264单视频的转发)代理转发主要 对于并发量并不大而且对性能 ...

  7. CCF - 最大矩形

    试题编号: 201312-3 试题名称: 最大的矩形 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n ...

  8. 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

    问题一:多线程有几种实现方法?同步有几种实现方法? 多线程有两种实现方法,分别是继承Thread类与实现Runnable接口   同步的实现方面有两种,分别是synchronized,wait与not ...

  9. Integer.valueOf

    一. 深入代码   在创建数字 1 的对象时, 大多数人会使用 new Integer(1), 而使用 Integer.valueOf(1) 可以使用系统缓存,既减少可能的内存占用,也省去了频繁创建对 ...

  10. 使用 JMeter 完成常用的压力测试 [转]

    讲到测试,人们脑海中首先浮现的就是针对软件正确性的测试,即常说的功能测试.但是软件仅仅只是功能正确是不够的.在实际开发中,还有其它的非功能因素也起着决定性的因素,例如软件的响应速度.影响软件响应速度的 ...