[国家集训队2011]happiness(吴确) (最小割)

2017-08-09 19:03:49

【试题来源】

2011中国国家集训队命题答辩

【问题描述】

高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值。作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大。

【输入格式】

第一行两个正整数n,m。
接下来是六个矩阵
第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择文科获得的喜悦值。
第二个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学选择理科获得的喜悦值。
第三个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择文科获得的额外喜悦值。
第四个矩阵为n-1行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i+1行第j列的同学同时选择理科获得的额外喜悦值。
第五个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择文科获得的额外喜悦值。
第六个矩阵为n行m-1列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学与第i行第j+1列的同学同时选择理科获得的额外喜悦值。

【输出格式】

输出一个整数,表示喜悦值总和的最大值

【样例输入】

1 2
1 1
100 110
1
1000

【样例输出】

1210

【样例说明】

两人都选理,则获得100+110+1000的喜悦值。

【数据规模和约定】

对于10%以内的数据,n,m<=4
对于30%以内的数据,n,m<=8
对于100%以内的数据,n,m<=100 数据保证答案在2^30以内
对于100%的数据,时间限制为0.5s。

明显最小割  题解 这里有 http://blog.sina.com.cn/s/blog_c5566b0f0102v7yo.html

讲的超级详细,很好理解。

建图好恶心

  1 #include<queue>
  2 #include<cstdio>
  3 #include<iostream>
  4 #define MAXN 200010
  5
  6 using namespace std;
  7
  8 const int INF=0x7fffffff;
  9
 10 struct node {
 11     int to;
 12     int next;
 13     int val;
 14 };
 15 node e[MAXN];
 16
 17 int head[MAXN],cur[MAXN],tot=1;
 18
 19 int depth[MAXN],ans,map[2][110][110],src,decc,p,sum;
 20
 21 int n,m;
 22
 23 queue<int> q;
 24
 25 inline void read(int&x) {
 26     int f=1;x=0;char c=getchar();
 27     while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();}
 28     while(c>=‘0‘&&c<=‘9‘) {x=(x<<1)+(x<<3)+c-48;c=getchar();}
 29     x=x*f;
 30 }
 31
 32 inline int cal(int i,int j) {
 33     return (i-1)*m+j;
 34 }
 35
 36 inline void add(int x,int y,int z) {
 37     e[++tot].to=y;
 38     e[tot].val=z;
 39     e[tot].next=head[x];
 40     head[x]=tot;
 41 }
 42
 43 inline void add_edge(int x,int y,int z,int f) {
 44     if(!f) {
 45         add(x,y,z);
 46         add(y,x,0);
 47     }
 48     else {
 49         add(x,y,z);
 50         add(y,x,z);
 51     }
 52 }
 53
 54 bool bfs() {
 55     for(int i=0;i<=decc;i++) cur[i]=head[i],depth[i]=-1;
 56     while(!q.empty()) q.pop();
 57     q.push(src);
 58     depth[src]=0;
 59     while(!q.empty()) {
 60         int u=q.front();
 61         q.pop();
 62         for(int i=head[u];i!=-1;i=e[i].next) {
 63             int to=e[i].to;
 64             if(e[i].val&&depth[to]==-1) {
 65                 q.push(to);
 66                 depth[to]=depth[u]+1;
 67                 if(to==decc) return true;  //卧槽 连return都忘了 只剩一个true 找了好长时间的错
 68             }
 69         }
 70     }
 71     return false;
 72 }
 73
 74 int dfs(int now,int flow) {
 75     if(now==decc) return flow;
 76     int rest=0,delat;
 77     for(int & i=cur[now];i!=-1;i=e[i].next) {
 78         int to=e[i].to;
 79         if(e[i].val&&depth[to]==depth[now]+1) {
 80             delat=flow-rest;
 81             delat=dfs(to,min(e[i].val,delat));
 82             e[i].val-=delat;
 83             e[i^1].val+=delat;
 84             rest+=delat;
 85             if(rest==flow) return flow;
 86         }
 87     }
 88     if(!rest) depth[now]=-1;
 89     return rest;
 90 }
 91
 92 inline void dinic() {
 93     while(bfs())
 94       ans+=dfs(src,INF);
 95     return;
 96 }
 97
 98 inline int hhh(){
 99     freopen("nt2011_happiness.in","r",stdin);
100     freopen("nt2011_happiness.out","w",stdout);
101     read(n);read(m);
102     fill(head,head+1+MAXN,-1);
103     src=0;decc=n*m+1;
104     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(map[0][i][j]),sum+=map[0][i][j],map[0][i][j]<<=1;
105     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(map[1][i][j]),sum+=map[1][i][j],map[1][i][j]<<=1;
106     for(int i=1;i<n;i++)
107       for(int j=1;j<=m;j++) {
108         read(p);
109         map[0][i][j]+=p;map[0][i+1][j]+=p;
110         sum+=p;
111         add_edge(cal(i,j),cal(i+1,j),p,1);
112       }
113     for(int i=1;i<n;i++)
114       for(int j=1;j<=m;j++) {
115         read(p);
116         map[1][i][j]+=p;map[1][i+1][j]+=p;
117         sum+=p;
118         add_edge(cal(i,j),cal(i+1,j),p,1);
119       }
120     for(int i=1;i<=n;i++)
121       for(int j=1;j<m;j++) {
122           read(p);
123         map[0][i][j]+=p;map[0][i][j+1]+=p;
124         sum+=p;
125         add_edge(cal(i,j),cal(i,j+1),p,1);
126       }
127     for(int i=1;i<=n;i++)
128       for(int j=1;j<m;j++) {
129           read(p);
130         map[1][i][j]+=p;map[1][i][j+1]+=p;
131         sum+=p;
132         add_edge(cal(i,j),cal(i,j+1),p,1);
133       }
134     for(int i=1;i<=n;i++)
135       for(int j=1;j<=m;j++)
136         add_edge(src,cal(i,j),map[0][i][j],0),
137         add_edge(cal(i,j),decc,map[1][i][j],0);
138
139     dinic();
140     printf("%d\n",sum-(ans>>1));
141     return 0;
142 }
143
144 int sb=hhh();
145 int main() {;}

代码

时间: 2024-10-06 16:58:33

[国家集训队2011]happiness(吴确) (最小割)的相关文章

国家集训队2011]happiness(吴确)

1873. [国家集训队2011]happiness(吴确) ★★★   输入文件:nt2011_happiness.in   输出文件:nt2011_happiness.out   简单对比时间限制:1 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,

国家集训队2011 happiness

[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文科或者理科,那么他们又将收获一些喜悦值.作为计算机竞赛教练的scp大老板,想知道如何分配可以使得全班的喜悦值总和最大. [输入格式] 第一行两个正整数n,m.接下来是六个矩阵第一个矩阵为n行m列 此矩阵的第i行第j列的数字表示座位在第i行第j列的同学

【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)

2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1511  Solved: 728 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定

[Bzoj2039][2009国家集训队]employ人员雇佣(最小割)

2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1988  Solved: 951[Submit][Status][Discuss] Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利

【BZOJ2039】【2009国家集训队】employ人员雇佣 最小割

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42651751 其实我就是觉得原创的访问量比未授权盗版多有点不爽233... 最小割心得: 首先需要一定的功底来发现这道题是最小割,并且投入思考. 然后想怎么建图: 最小割都是先算上所有收益,然后再通过网络图进行割边减去部分权值. 收益有时候可能带上负值. 然后我们需要思考什么能带来权值,什么会有权值冲突. 而最小割图一般都是拆成S集和T集考虑,即取与不取,某人/点选A或者选B等等, 这样

BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割

Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定的金钱Ai,对于一些经理可能他做出的贡献不值得他的花费,那么作为一个聪明的人,小L当然不会雇佣他. 然而,那些没有被雇佣的人会被竞争对手所雇佣,这个时候那些人会对你雇佣的经理的工作造成影响

[国家集训队2011]旅游(宋方睿)

1867. [国家集训队2011]旅游(宋方睿) ★★★★   输入文件:nt2011_travel.in   输出文件:nt2011_travel.out   简单对比时间限制:1 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题描述] Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径.换句话说,T 城中只有N - 1

cogs 1901. [国家集训队2011]数颜色

Cogs 1901. [国家集训队2011]数颜色 ★★★   输入文件:nt2011_color.in   输出文件:nt2011_color.out   简单对比时间限制:0.6 s   内存限制:512 MB [试题来源] 2011中国国家集训队命题答辩 [问题描述] 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令:1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔.2. R P Col 把第P支画笔替换为

[补档][国家集训队2011]单选错位

题目 gx和lc去参加noip初赛,其中有一种题型叫单项选择题,顾名思义,只有一个选项是正确答案. 试卷上共有n道单选题,第i道单选题有ai个选项,这ai个选项编号是1,2,3,-,ai,每个选项成为正确答案的概率都是相等的.lc采取的策略是每道题目随机写上1-ai的某个数作为答案选项,他用不了多少时间就能期望做对sigma(1/ai)道题目.gx则是认认真真地做完了这n道题目,可是等他做完的时候时间也所剩无几了,于是他匆忙地把答案抄到答题纸上,没想到抄错位了:第i道题目的答案抄到了答题纸上的第