All submissions for this problem are available.

Read problems statements in Mandarin Chineseand 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

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

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

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;
}

Course Selection CodeChef - RIN的更多相关文章

  1. CodeChef - RIN Course Selection

    Read problems statements in Mandarin Chineseand Russian. Rin is attending a university. She has M se ...

  2. Codechef RIN 「Codechef14DEC」Course Selection 最小割离散变量模型

    问题描述 提供中文版本好评,一直以为 Rin 是题目名字... pdf submit 题解 参考了 东营市胜利第一中学姜志豪 的<网络流的一些建模方法>(2016年信息学奥林匹克中国国家队 ...

  3. [CODECHEF]RIN

    题意:一个人要在$m$个学期上$n$节课,在第$j$学期上$i$课有$X_{i,j}$的收益,有些课$B_i$有前置课程$A_i$,问最大得分 这个题我都做不出来还去看题解...我退役吧== 考虑每种 ...

  4. CodeChef - RIN 最小割应用 规划问题

    题意:给定\(n\)门课和\(m\)个学期,每门课在每个学期有不同的得分,需要选定一个学期去完成,但存在约束条件,共有\(k\)对课程需要\(a\)在\(b\)开始学前学会,求最大得分(原问题是求最高 ...

  5. [CodeChef]RIN(最小割)

    Description  有m门课可以在n个学期内学习,第i门课在第j个学期的收益是\(X_{i,j}\),一个学期可以学多门课,有的课之间有依赖关系,即必须先学a再学b,求最大收益.n,m<= ...

  6. Codechef Course Selection

    Home » Practice(Hard) » Course Selection Course Selection Problem Code: RINSubmit https://www.codech ...

  7. codechef营养题 第三弹

    第三弾が始まる! codechef problems 第三弹 一.Motorbike Racing 题面 It's time for the annual exciting Motorbike Rac ...

  8. codechef营养题 第二弹

    第二弾が始まる! codechef problems 第二弹 一.Backup Functions 题面 One unavoidable problem with running a restaura ...

  9. codechef 营养题 第一弹

    第一弾が始まる! 定期更新しない! 来源:http://wenku.baidu.com/link?url=XOJLwfgMsZp_9nhAK15591XFRgZl7f7_x7wtZ5_3T2peHh5 ...

随机推荐

  1. NS3网络仿真(6): 总线型网络

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载.但请保留作者信息 在NS3提供的第一个演示样例first.py中,模拟了一个点对点的网络,接下来的一个演示样例代码模 ...

  2. unity, multi collider

    比如下面鸭子模型,只用一个box collider难以很好地吻合其的外形. 我们可以为它添加两个box collider,如下图所示: 注意: 1,colliders一定要添加在模型根节点(即图中do ...

  3. Xamarin for VS 4.0.1.145 Stable版免费完整破解补丁

    Xamarin for VS 4.0.1.145 Stable版免费完整破解补丁 支持Priority最高权限(超企业版)开发, 支持Android, IOS调试.  支持Android打包为Bund ...

  4. Handler实例

    Handler使用例1这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.本次实验完成的功能是:单击Start按钮,程序会开始启动线程,并且线程程序完成后延时1s会继 ...

  5. python模块之XlsxWriter 详解

    Xlsx是python用来构造xlsx文件的模块,可以向excel2007+中写text,numbers,formulas 公式以及hyperlinks超链接. 可以完成xlsx文件的自动化构造,包括 ...

  6. poj3067 Japan(树状数组)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:id=3067">http://poj.org/problem? id=3067 Descri ...

  7. qt 多点触摸

    http://www.ptrackapp.com/apclassys-notes/embedded-linux-multitouch/ Embedded Linux Multitouch with Q ...

  8. /proc/meminfo分析

    参考: 1. linux/Documentation/filesystems/proc.txt 2. Linux 中 /proc/meminfo 的含义 3. redhat deployment gu ...

  9. nginx的root alias 指令

    location /img/ { alias /var/www/image/; } #若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件 ...

  10. C#_GDI+编程教程

    第7章  C#图形图像编程基础 本章主要介绍使用C#进行图形图像编程基础,其中包括GDI+绘图基础.C#图像处理基础以及简单的图像处理技术. 7.1  GDI+绘图基础 编写图形程序时需要使用GDI( ...