3713. 【NOI2014模拟6.30】Honor(honor)

Description

小K和同学们期待已久的暑假即将到来。然而小K的班主任兼德育处主任却莫名失踪了一个月。据小道消息,他在高考后才会出现。但现在德育处有诸多繁杂的工作,确定每个班的“三好学生”便是最令人头痛的。

    HY中学的大Boss圆规要求N个班的班主任按照学生的综合素质推荐学生。但他深深地知道,每个班主任都会无一例外地使用xls把M名学生数次月考成绩相加排序,然后从高到底依次录取。圆规知道每个班学生成绩的排序和每个学生得到该荣誉的“负”能量Aij。显然,“负”能量也是有正有负的。他不希望有些学生拿到“三好学生”后依然肆无忌惮地拔掉教室里监控的探头,或是在晚餐时间在篮球场上尽情玩耍(这在HY中学是会被通报批评的)。他希望能够多发扬正能量。

    圆规从不在乎“三好学生”的数量,但是他却不得不考虑学生的感受。学生在学生会上

(1)提出了K条无理的要求,每条要求对于班级u、v,要求班级u的三好学生数量Su和班级v三好学生数量Sv,满足Su-Sv<=w。

(2)提出每个班至少一张奖状。

    鉴于HY中学的高一高二学生在5月下旬某一个酷热的晚上,忍无可忍围起了整栋教学楼,并且齐声高声叫喊:“开空调!”但学校善后处理十分不得力。圆规决定全盘接受学生的建议,以平息学生的怒气。但是,他还是想知道最小的负能量。

Input

第1行 为三个数N、M、K如题意所示。

    第2-N+1行,每行M个数,表示按成绩从高到底排序的每个学生的“负”能量大小。

    第N+2-N+K+1行,每行三个数u、v、w如题意所示。

Output

最小的负能量。

Sample Input

3 4 3

13 -4 -1 -2

1 -2 3 1

-3 4 2 1

2 3 0

3 2 0

1 2 1

Sample Output

7

Data Constraint

20%的数据 n,m<=10;

50%的数据 n,m<=30,K<=500

70%的数据 n,m<=50,K<=2000

100%的数据 n<=900,m<=60,K<=20000,Aij的绝对值小于1000,w<=1000。

Solution

可以转化为网络流模型。

建立源点和汇点,每班第一人从源点连一条inf容量的边,每班每个同学向后一个同学连边,边权为前i个同学的负能量之和。每班最后一个人向汇点同样连这个班所有人的负能量之和。因为要求每个班必须选,因此不能割从源点到第一个人的边,除此之外,每割一条边表示选了这个班的前i个人。对于一个限制条件,班级v最多能比班级u少选w个人。也就是说割了班级u的第i点的边后,班级v的第i-w的点之前的边就都不能割,那么我们从u班的i这个点向v班i-w连一条inf的边即可,最后跑一边最小割就是答案了。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define I int
#define ll long long
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 2147483647
#define N 910
#define M 3100000
using namespace std;

I rd(I &x){
	x=0;I w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	x*=w;
}
I n,m,k,tot,mi,S,T,a[N][100],id[N][100],d[N*110],q[N*110],ans,flow;
I t[M],nx[M],l[N*100],s[M];
void add(I x,I y,I z){
	t[++t[0]]=y,nx[t[0]]=l[x],l[x]=t[0],s[t[0]]=z;
	t[++t[0]]=x,nx[t[0]]=l[y],l[y]=t[0],s[t[0]]=0;
}
I bfs(){
	mem(d,0);
	q[1]=S;I i=0,j=1;d[S]=1;
	while(i<j){
		I x=q[++i];
		for(I k=l[x];k;k=nx[k]) if(s[k]&&!d[t[k]]){
			q[++j]=t[k];
			d[t[k]]=d[x]+1;
			if(t[k]==T) return 1;
		}
	}
	return 0;
}
I dinic(I x,I fl){
	if(x==T) return fl;
	I r=fl,st;
	for(I k=l[x];k&&r;k=nx[k]) if(s[k]&&d[t[k]]==d[x]+1){
		st=dinic(t[k],min(r,s[k]));
		if(!st) d[t[k]]=0;
		s[k]-=st;s[k^1]+=st;
		r-=st;
	}
	return fl-r;
}
I main(){
	freopen("honor.in","r",stdin);
	freopen("honor.out","w",stdout);
	rd(n),rd(m),rd(k);
	F(i,1,n){
		F(j,1,m){
			rd(a[i][j]);a[i][j]+=a[i][j-1];
			mi=min(mi,a[i][j]);
			id[i][j]=++tot;
		}
	}
	S=++tot,T=++tot;t[0]=1;
	F(i,1,n){
		add(S,id[i][1],inf);
		F(j,1,m){
			a[i][j]-=mi;
			if(j==m)add(id[i][j],T,a[i][j]);
			else add(id[i][j],id[i][j+1],a[i][j]);
		}
	}
	I x,y,z;
	while(k--){
		rd(x),rd(y),rd(z);
		F(i,1,m) if(i-z) add(id[x][i],id[y][i-z],inf);
	}
	flow=0;
	while(bfs()){
		while(flow=dinic(S,inf)) ans+=flow;
	}
	printf("%d\n",ans+mi*n);
	return 0;
}
发布了199 篇原创文章 · 获赞 201 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zsjzliziyang/article/details/103674424