计蒜客 课程规划(景驰无人驾驶1024编程邀请赛 D)
来源:互联网 发布:linux vim命令模式 编辑:程序博客网 时间:2024/04/29 20:39
在 T 大 X 院,每年都要安排课程。所需要安排的课程分为 mm 个课组,每门课组有不超过 TT 门课,共有 NN 名教授可以教课。聘请教授 ii,X 院需要花费经费 c_ic
i
,一名教授可以教某个课组里面的两门课,但当年只能聘请他教其中一门。
在每个课组还可以被分成小课组,如果把每门课程看成一个点,每名教授看成连接两门课程的边,则这样得到的图中的每个连通块被称作一个小课组,显然一个课组由若干小课组组成。学校规定,聘请的教授最后要使得总的小课组数目保持不变(与聘请所有教授的总小课组数一致),且能满足开设的课程尽量多。
对于不同课组,学校有不同的资助政策,具体来说,对于第 ii 个课组,学校最多可以为 X 院出钱聘请 p_ip
i
名教授。但总共只能资助不超过 WW 门课。
由于 X 院经费有限,他们希望能够充分利用学校的政策,在开设尽量多课程的前提下,花费最少的经费聘用教授。
输入格式
第一行输入测试组数 T(1 \le T \le 10)T(1≤T≤10)。
对于每一组测试数据,第一行三个数, N(N \le 100000)N(N≤100000),m( m \le 5000)m(m≤5000),T(T \le 100000)T(T≤100000),W(W \le 100)W(W≤100)。意义如题目中所述。
接下来 NN 行,每行 44 个数 d_i,a_i,b_i,c_id
。表示第 ii 名教授可以教第 d_id
i
个课组里的第 a_ia
i
门课和第 b_ib
i
门课,聘请他的费用是 c_ic
i
。
接下来一行 mm 个数,p_1,p_2,\cdots,p_m(0 \le p_i \le 10)p
输入保证最终答案小于 2^{31}2
31
。
输出格式
对于每一组数据,输出两行,第一行表示最多开设多少门课,第二行表示在开设最多课的基础上最少花费多少钱。
样例输入
1
4 2 3 1
1 1 2 1
1 2 3 3
1 3 1 4
2 1 2 3
1 1
样例输出
4
i
,一名教授可以教某个课组里面的两门课,但当年只能聘请他教其中一门。
在每个课组还可以被分成小课组,如果把每门课程看成一个点,每名教授看成连接两门课程的边,则这样得到的图中的每个连通块被称作一个小课组,显然一个课组由若干小课组组成。学校规定,聘请的教授最后要使得总的小课组数目保持不变(与聘请所有教授的总小课组数一致),且能满足开设的课程尽量多。
对于不同课组,学校有不同的资助政策,具体来说,对于第 ii 个课组,学校最多可以为 X 院出钱聘请 p_ip
i
名教授。但总共只能资助不超过 WW 门课。
由于 X 院经费有限,他们希望能够充分利用学校的政策,在开设尽量多课程的前提下,花费最少的经费聘用教授。
输入格式
第一行输入测试组数 T(1 \le T \le 10)T(1≤T≤10)。
对于每一组测试数据,第一行三个数, N(N \le 100000)N(N≤100000),m( m \le 5000)m(m≤5000),T(T \le 100000)T(T≤100000),W(W \le 100)W(W≤100)。意义如题目中所述。
接下来 NN 行,每行 44 个数 d_i,a_i,b_i,c_id
。表示第 ii 名教授可以教第 d_id
i
个课组里的第 a_ia
i
门课和第 b_ib
i
门课,聘请他的费用是 c_ic
i
。
接下来一行 mm 个数,p_1,p_2,\cdots,p_m(0 \le p_i \le 10)p
输入保证最终答案小于 2^{31}2
31
。
输出格式
对于每一组数据,输出两行,第一行表示最多开设多少门课,第二行表示在开设最多课的基础上最少花费多少钱。
样例输入
1
4 2 3 1
1 1 2 1
1 2 3 3
1 3 1 4
2 1 2 3
1 1
样例输出
4
7
分析:光是读题就读了一晚上和一上午,最后才明白就是一水题,最小生成树!!!
仔细独读题就知道 就是对每一个连通块求最小生成树 然后在最小生成树上在加一条可以值尽量小的边使得干好使得每一个点都能匹配一条边既一个课程一个老师(或者没有边可加)。
找出那些边后 就是 把最大值贪心就行!
#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<vector>const int maxn = 100000;const int inf = 1e9;typedef long long ll;using namespace std;struct Edge{ int x,y,c,tid;}e[maxn+5];int n,m,T,w,pos[maxn+5],pos_tot,ans_clas,ans_cost;int p[5015],fa[maxn+5],used[5015],vis[maxn+5];vector<int>clas[5015];int find_fa(int x){ if(fa[x] == -1) return x; return fa[x] = find_fa(fa[x]);}bool cmp(int i,int j){ return e[i].c < e[j].c;}bool cmp2(int i,int j){ return e[i].c > e[j].c;}int main(){ int Cas; scanf("%d",&Cas); while(Cas--) { scanf("%d %d %d %d",&n,&m,&T,&w); for(int i=0;i<=m;i++) clas[i].clear(); for(int i=1;i<=n;i++) { scanf("%d %d %d %d",&e[i].tid,&e[i].x,&e[i].y,&e[i].c); clas[e[i].tid].push_back(i); } for(int i=1;i<=m;i++) scanf("%d",&p[i]); pos_tot = ans_cost = ans_clas = 0; for(int c=1;c<=m;c++) { int len = clas[c].size(), cnt = 0,tot=0; for(int i=1;i<=T;i++) fa[i] = -1,vis[i]=0; for(int i=0;i<len;i++)//求有多少连通块 { Edge E = e[clas[c][i]]; int fx,fy; fx = find_fa(E.x), fy = find_fa(E.y); vis[E.x] = vis[E.y] = 1; if(fx!=fy) fa[fx] = fy; } for(int i=1;i<=T;i++) if(vis[i]) tot++; for(int i=1;i<=T;i++) if(fa[i]==-1&&vis[i]) cnt++; for(int i=0;i<len;i++) used[i] = 0; sort(clas[c].begin(),clas[c].end(),cmp);//把边排序 cnt = tot - cnt;// 要把这些连通块 生成树 需要边的数量 ans_clas += cnt; for(int i=1;i<=T;i++) fa[i] = -1; for(int i=0,t=0;i<len&&t<cnt;i++)// 最小生成树 { Edge E = e[clas[c][i]]; int fx,fy; fx = find_fa(E.x), fy = find_fa(E.y); if(fx!=fy) { t++, used[i] = 1; fa[fx] = fy; ans_cost+=E.c; pos[++pos_tot] = clas[c][i];//记录 要取的边 } } for(int i=1;i<=T;i++) vis[i] = 0; for(int i=0;i<len;i++)// 在生成树上 加一条边 { if(used[i]) continue; Edge E = e[clas[c][i]]; int fx = find_fa(E.x); if(vis[fx]) continue;// 一个连通块只能加一条 vis[fx] = 1; ans_clas++,pos[++pos_tot] = clas[c][i],ans_cost+=E.c; } } sort(pos+1,pos+pos_tot+1,cmp2);//把要取的边排序 for(int i=1;i<=pos_tot&&w;i++)//贪心! { int id = e[pos[i]].tid; if(p[id]) { p[id]--,w--; ans_cost-=e[pos[i]].c; } } printf("%d\n",ans_clas); printf("%d\n",ans_cost); } return 0;}
阅读全文
0 0
- 计蒜客 课程规划(景驰无人驾驶1024编程邀请赛 D)
- 景驰无人驾驶 1024 编程邀请赛
- 景驰无人驾驶 1024 编程邀请赛 A 热爱工作的蒜蒜 dijstra
- 景驰无人驾驶 1024 编程邀请赛 A.热爱工作的蒜蒜【二维最短路】
- 景驰无人驾驶 1024 编程邀请赛 A.热爱工作的蒜蒜(最短路,SPFA)
- 景驰无人驾驶 1024 编程邀请赛 A 题 【最短路 + 思维】
- 景驰无人驾驶 1024 编程邀请赛 A. 热爱工作的蒜蒜(类似DP的最短路)
- 无人驾驶课程准备
- 【D类】编程开发视频课程系列
- 地大邀请赛d
- 无人驾驶中的决策规划控制技术
- 2015湘潭邀请赛 D.Fraction
- 无人驾驶
- 无人驾驶
- WebGIS课程规划设计
- HDUOJ 4496 通化邀请赛重现 D-City
- 15年湘潭邀请赛 D题 Fraction
- 16 hrbust邀请赛D、F题解
- Andriodjie——简单的购物车全选反选
- modelsim新建工程进行功能仿真
- 关于Unity渲染优化,你可能遇到这些问题
- mfc socket发送和接收数据和文件
- 训练GAN网络的技巧
- 计蒜客 课程规划(景驰无人驾驶1024编程邀请赛 D)
- 一分钟ECS上搭建云HBase Thriftserver
- 需要了解的相关知识
- QT安装问题
- 洛谷P1082 同余方程
- TensorFlow基本操作及函数
- spark 日常
- spring boot:Scheduling Tasks
- 爬格子呀6-4、6-5、6-9