Course Selection CodeChef – RIN

Course Selection CodeChef – RIN

大家好,又见面了,我是全栈君。

All submissions for this problem are available.

Read problems statements in Mandarin Chinese and Russian.

Rin is attending a university.

She has M semesters to finish her program, and that program has N required courses. Each course must be taken in exactly one of the semesters.

Some courses have prerequisites: for each i from 1 to K, she must take course A[i]before course B[i].

The same course may be taught by different professors in different semesters, and how well she does will depend on which professor teaches her. Additionally, some courses may not be taught every semester.

We are given an array X representing this information. For each course i and each semester j, X[i][j] = -1 if course i is not taught in semester j. Otherwise, X[i][j] will be an integer between 0 and 100: the expected score Rin will get if she takes course i in semester j.

Rin may take any number of courses per semester, including none, as long as they are taught that semester and she has already taken any required prerequisite courses.

Help Rin to find the maximal average score she can get over her whole program.

Input

The first line contain 3 integers: N, M and K.

This is followed by N lines, each containing M integers. The jth integer on the ith line represents the value of X[i][j].

This is followed by K lines, each containing two integers: A[i] and B[i].

Output

Output one real number: the maximal average score, rounded to 2 digits after the decimal point.

Constraints

  • 1 ≤ M, N ≤ 100
  • 0 ≤ K ≤ 100
  • -1 ≤ X[i][j] ≤ 100
  • 1 ≤ A[i], B[i] ≤ N
  • For each i, A[i] ≠ B[i].
  • For different i and j, (A[i], B[i]) ≠ (A[j], B[j]).
  • We guarantee there exists a way to take these N courses in M semesters.

Subtasks

Subtask 1: (20 Points) A course can have at most 1 pre request course.

Subtask 2: (80 Points) Refer to constraints above

Example

Input 1:
3 2 2
70 100
100 80
100 90
1 2
1 3

Output 1:
80.00

Input 2:
4 5 4
20 -1 100 -1 -1
100 30 -1 -1 -1
100 -1 30 20 40
100 30 40 50 20
1 2
1 3
2 4
3 4

Output 2:
32.50

Explanation

Example case 1

The only way she can finish these 3 courses is: take course 1 in the first semester, then take courses 2 and 3 in the second semester. The average score is (70 + 80 + 90) / 3 = 80.00.

Example case 2

The optimal solution is: take course 1 in semester 1, course 2 in semester 2, course 3 in semester 3 and course 4 in semester 4.

EXPLANATION:

First, let’s ignore the dependencies. The answer is just the maximum grade per course in any of the semesters, which is trivial to compute but let’s put this in another perspective:

For each course, the best grade is 100 – (minimum grade we lose by picking one of the semesters).

To model this as a network flow graph, we do 4 things:

  1. Create a vertex for each pair (course i, semester j).
  2. Create a source vertex which is connected to the first semester of each course i by an edge with capacity 100 – grade(i, 1).
  3. For every semester j from 2 to M, connect the vertices of each course i from semester j-1 to j with capacity 100 – grade(i, j) or 100 if the course is not available (it’s the same as having grade 0, recall that it’s guaranteed there is a solution).
  4. Create a sink vertex and connect the last semester of each course to it, with infinite capacity.

Consider the following example with 3 courses and 3 semesters:

3 3
10 70 100
80 50 40
80 20 40

alt text

The corresponding graph is depicted in the above picture. The maximum flow is equal to the combined grade loss for all courses. We pick semester 3 for course 1 (zero loss), and semester 1 for courses 2 and 3 (loss 20+20). The maximum grade average we can get is (N * 100 – maxflow) / N. In this case: (3*100 – 40) / 3 ~= 86.67.

– Returning to the problem, why does this help?

If we model the problem this way, we can also include the course dependencies. Suppose there are dependencies 1->2 and 1->3. The best we can do is course 1 in semester 2 and courses 2 and 3 in semester 3 for (70+40+40)/3 average.

– If there are dependencies 1->2 and 1->3, then courses 2 and 3 can never be done in the first semester.

This implies that the minimum grade loss for courses 2 and 3 is not bounded by its grades in semester 1. This is the same as changing the capacities associated to semester 1 of courses 2 and 3 to infinity.

– Why do we pick semester j for course 1?

The combined grade loss of doing course 1 in semester 2 + courses 2 and 3 in semester 3 is less than doing course 1 in semester 1 + courses 2 and 3 in semesters 2 or 3.

In terms of network flow, this means that

  • if we pick semester j = 1, then courses 2 and 3 are not bounded by grade loss in semester 1. To combine the grade loss by picking semester 1, we connect vertex (course 1, semester 1) to (course 2, semester 2) and (course 3, semester 2) with infinite capacity.
  • if we pick semester j = 2, then courses 2 and 3 are not bounded by grade loss in semesters 1 and 2. Same as above but connecting (course 1, semester 2) to courses 2 and 3, semester 3.
  • picking semester j = 3 is not possible.

The resulting network is the following

Course Selection CodeChef - RIN

We can see that the maximum flow is 150. The best is to distribute the grade loss of course 1 in semester 2, flow 3, among courses 2 and 3 in semester 3. In fact, 70+40+40 = 300 – 150.

To give you another example, consider the input

3 3 2
10 50 100
80 90 40
80 40 70
1 2
1 3

The best we can do course 1 at semester 1 (10) + course 2 at semester 2 (90) and course 3 at semester 3 (70) = 10+90+70. The resulting graph is

alt text

We can see that the maximum flow is 130 because in this case, it is better to distribute the grade loss of course 1 at semester 1, the flow 90, among the grade loss of courses 2 and 3 over semesters 2 and 3, respectively.

In a nutshell, we create a graph with N*M+2 vertices and use a standard maximum flow algorithm. The hard part was to realize how to build the network correctly.

Proof sketch:

Since max-flow equals min-cut, we can think of our problem as of finding a minimum cut in the above graph. Let Pi be a path corresponding to i-th course, i.e. the path formed of edges corresponding to i-th course in all semesters. In order to prove the correction of the above construction, we can show two properties of the graph:

  1. For every 1 <= i <= N, min-cut contains exactly one edge from Pi.
  2. For every constraint (i, j), if min-cut contains the k-th edge of Pi, then it contains the x-th edge of Pj, where x > k i.e. j-th course is taken in later semester than i-th course.

These two fact can be shown quite easily, but we will omit exact proofs here. Intuitively, if you pick any edge from Pi, then Pi is disconnected and there is no need for taking any other edge from it. Moreover, an edge (i, j) corresponding to a constraint, prevent us of taking course j before course i, because if you did it, then in order to make the graph disconnected, you would have to add the second edge of Pj to min-cut which contradicts the first fact.

Select Code
#include<cstdio>
#include<cstring>
#include<iostream>
#define inf 2e9
using namespace std;
const int Z=101;
const int N=Z*Z;
const int M=2e6+5;
struct edge{
   
   int v,next,cap;}e[M];int tot=1,head[N];
int n,m,k,cnt,ans,S,T,id[Z][Z],X[Z][Z],dis[N],q[M];
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
   
   if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline void add(int x,int y,int z){
	e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
	e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;
}
inline bool bfs(){
	for(int i=S;i<=T;i++) dis[i]=-1;
	int h=0,t=1;q[t]=S;dis[S]=0;
	while(h!=t){
		int x=q[++h];
		for(int i=head[x];i;i=e[i].next){
			if(e[i].cap&&dis[e[i].v]==-1){
				dis[e[i].v]=dis[x]+1;
				if(e[i].v==T) return 1;
				q[++t]=e[i].v;
			}
		}
	}
	return 0;
}
int dfs(int x,int f){
	if(x==T) return f;
	int used=0,t;
	for(int i=head[x];i;i=e[i].next){
		if(e[i].cap&&dis[e[i].v]==dis[x]+1){
			t=dfs(e[i].v,min(e[i].cap,f));
			e[i].cap-=t;e[i^1].cap+=t;
			used+=t;f-=t;
			if(!f) return used;
		}
	}
	if(!used) dis[x]=-1;
	return used;
}
inline void dinic(){
	while(bfs()) ans-=dfs(S,inf);
}
inline int getY(int x){
	if(~x) return 100-x;
	return inf;
}
int main(){
	n=read();m=read();k=read();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			X[i][j]=read();
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			id[i][j]=++cnt;
		}
	}
	S=0,T=n*m+1;
	for(int i=1;i<=n;i++){
		add(S,id[i][1],getY(X[i][1]));
		for(int j=2;j<=m;j++) add(id[i][j-1],id[i][j],getY(X[i][j]));
		add(id[i][m],T,inf);
	}
	for(int i=1,a,b;i<=k;i++){
		a=read();b=read();
		add(S,id[b][1],inf);
		for(int j=2;j<=m;j++) add(id[a][j-1],id[b][j],inf);
	}
	ans=100*n;
	dinic();
	printf("%.2lf",1.0*ans/n);
	return 0;
}

 

转载于:https://www.cnblogs.com/shenben/p/6624196.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108595.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 自制51单片机最小系统开发板[通俗易懂]

    自制51单片机最小系统开发板[通俗易懂]2.单片机最小系统介绍单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计

    2022年6月23日
    23
  • 【转载】句柄和指针的区别

    【转载】句柄和指针的区别

    2021年11月18日
    36
  • DLL注入原理分析

    DLL注入原理分析所谓DLL注入就是将一个DLL放进某个进程的地址空间里,让它成为那个进程的一部分。要实现DLL注入,首先需要打开目标进程。1、附加到目标/远程进程hRemoteProcess=OpenProcess(PROCESS_CREATE_THREAD|//允许远程创建线程PROCESS_VM_OPERATION |//允许远程VM操作PROCESS_VM_WRITE, //允许…

    2022年5月16日
    43
  • 回归分析中自变量取舍、检验及多重共线性处理(VIF)「建议收藏」

    回归分析中自变量取舍、检验及多重共线性处理(VIF)「建议收藏」A1正交假定:误差项矩阵与X中每一个x向量都不相关高斯-马尔科夫定理:若满足A1和A2假定,则采用最小二乘法得到回归参数估计是最佳线性无偏估计方程估计值b1和b2可以看做偏回归系数,也是相应自变量对y的一种偏效应偏效应:在控制变量下,各自变量X对因变量Y的净效应残差项:针对具体模型而言,被定义为样本回归模型中观测值与预测值之差误差项:针对总体真实回归模型而言,它由一些不可观测因素或测量…

    2022年5月30日
    65
  • nessus使用教程扫描_Nessus扫描IP无结果

    nessus使用教程扫描_Nessus扫描IP无结果转载:https://www.cnblogs.com/youcanch/articles/5671238.htmlNessus号称是世界上最流行的漏洞扫描程序,全世界有超过75000个组织在使用它。该工具提供完整的电脑漏洞扫描服务,并随时更新其漏洞数据库。Nessus不同于传统的漏洞扫描软件,Nessus可同时在本机或远端上遥控,进行系统的漏洞分析扫描。Nessus也是渗透测试重要工具之一。所…

    2022年10月19日
    0
  • MQ学习笔记

    MQ学习笔记一、为什么要使用MQ?其实这里要讲的就是使用MQ的好处,MQ的的使用场景有很多,但是比较核心的有3个:解耦、异步、削峰1. 解耦例如:A系统要发送数据到B、C、D三个系统,通过接口调用发送。假如现在又添加了一个E系统,也要数据,A系统需要修改;B系统说我现在不需要这个数据了,A系统还是要修改。这种情况下,A系统的维护者肯定很崩溃。其实这个调用是不需要直接同步调用接口的,如…

    2022年6月13日
    67

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号