3894: 文理分科

题目:传送门

感谢波老师没有来D飞我,让我做出了这题...

题解:

   这题其实和我做的上一题(bzoj2132)很像,所以就不写题意了。

   依然是那最小割...

   这题给出了四个利益矩阵,看似比上一题复杂,想了很久,发现其实建图没有我想象的麻烦。

  首先复习一下最小割的定义:把原图分为两个不相交的子集(st和ed)

   那么这题用最小割来做的话,我们就把st当成文科的子集,ed为理科。

   对于任意的一个x点

   st到x连一条流量为文科利益的边,x到ed连一条流量为理科利益的边

   那么另外两个利益矩阵怎么处理呢?这里我们就要手动建一些新点

   对于任意的一个十字,这个十字中的点都是互相影响的,那么我们用一个新点分别连向十字中的所有点,流量为无限,然后st想这个新点连,流量为同选文科的利益

   再建一匹新点:

   对于任意的一个十字,这个十字中的点都是互相影响的,那么我们把十字中的所有点都想一个新点连边,流量为无限,然后这个新点向ed连,流量为同选理科的利益

   原理就YY吧。。。

上代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<algorithm>
  6. #define inf 999999999
  7. #define qread(x)x=read();
  8. using namespace std;
  9. inline int read()
  10. {
  11. int f=,x=;char ch;
  12. while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
  13. while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
  14. return f*x;
  15. }
  16. const int dx[]={,-,,,};
  17. const int dy[]={,,,-,};
  18. struct node
  19. {
  20. int x,y,c,next,other;
  21. }a[];int len,last[];
  22. int n,m,st,ed,head,tail;
  23. void ins(int x,int y,int c)
  24. {
  25. int k1,k2;
  26. k1=++len;
  27. a[len].x=x;a[len].y=y;a[len].c=c;
  28. a[len].next=last[x];last[x]=len;
  29.  
  30. k2=++len;
  31. a[len].x=y;a[len].y=x;a[len].c=;
  32. a[len].next=last[y];last[y]=len;
  33.  
  34. a[k1].other=k2;
  35. a[k2].other=k1;
  36. }
  37. int list[],h[];
  38. bool bt_h()
  39. {
  40. memset(h,,sizeof(h));h[st]=;
  41. list[]=st;head=;tail=;
  42. while(head!=tail)
  43. {
  44. int x=list[head];
  45. for(int k=last[x];k;k=a[k].next)
  46. {
  47. int y=a[k].y;
  48. if(h[y]== && a[k].c>)
  49. {
  50. h[y]=h[x]+;
  51. list[tail++]=y;
  52. }
  53. }
  54. head++;
  55. }
  56. if(h[ed]>)return true;
  57. return false;
  58. }
  59. int find_flow(int x,int flow)
  60. {
  61. if(x==ed)return flow;
  62. int s=,t;
  63. for(int k=last[x];k;k=a[k].next)
  64. {
  65. int y=a[k].y;
  66. if(h[y]==h[x]+ && a[k].c> && s<flow)
  67. {
  68. s+=t=find_flow(y,min(a[k].c,flow-s));
  69. a[k].c-=t;a[a[k].other].c+=t;
  70. }
  71. }
  72. if(s==)h[x]=;
  73. return s;
  74. }
  75. int w[][],l[][],sw[][],sl[][];
  76. int d[][];
  77. int main()
  78. {
  79. qread(n);qread(m);
  80. st=n*m*+;ed=st+;
  81. len=;memset(last,,sizeof(last));
  82. int ss=;
  83. for(int i=;i<=n;i++)for(int j=;j<=m;j++)d[i][j]=ss++;
  84. int sum=;
  85. for(int i=;i<=n;i++)for(int j=;j<=m;j++){qread(w[i][j]);ins(st,d[i][j],w[i][j]);sum+=w[i][j];}
  86. for(int i=;i<=n;i++)for(int j=;j<=m;j++){qread(l[i][j]);ins(d[i][j],ed,l[i][j]);sum+=l[i][j];}
  87. for(int i=;i<=n;i++)
  88. for(int j=;j<=m;j++)
  89. {
  90. qread(sw[i][j]);
  91. for(int k=;k<=;k++)
  92. if(d[i+dx[k]][j+dy[k]]>)
  93. ins(d[i][j]+n*m,d[i+dx[k]][j+dy[k]],inf);
  94. ins(st,d[i][j]+n*m,sw[i][j]);
  95. sum+=sw[i][j];
  96. }
  97. for(int i=;i<=n;i++)
  98. for(int j=;j<=m;j++)
  99. {
  100. qread(sl[i][j]);
  101. for(int k=;k<=;k++)
  102. if(d[i+dx[k]][j+dy[k]]>)
  103. ins(d[i+dx[k]][j+dy[k]],d[i][j]+n*m*,inf);
  104. ins(d[i][j]+n*m*,ed,sl[i][j]);
  105. sum+=sl[i][j];
  106. }
  107. int ans=;
  108. while(bt_h())ans+=find_flow(st,inf);
  109. printf("%d\n",sum-ans);
  110. return ;
  111. }

bzoj3894: 文理分科(还是那道最小割)的更多相关文章

  1. [bzoj3894]文理分科_网络流_最小割

    文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...

  2. BZOJ3894文理分科——最小割

    题目描述  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过)  小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行 描述,每个格子代表一个同学的座位.每位同学必须从 ...

  3. [Bzoj3894]文理分科(最小割)

    Description  文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过)  小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...

  4. 【题解】 bzoj3894: 文理分科 (网络流/最小割)

    bzoj3894,懒得复制题面,戳我戳我 Solution: 首先这是一个网络流,应该还比较好想,主要就是考虑建图了. 我们来分析下题面,因为一个人要么选文科要么选理科,相当于两条流里面割掉一条(怎么 ...

  5. Bzoj3894 文理分科

    Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 667  Solved: 389 Description  文理分科是一件很纠结的事情!(虽然看到这个题 ...

  6. [BZOJ3894]文理分科(最小割)

    (1) 对每个位置建一个点F1,S向这个点连art[i][j]的边,这个点向T连science[i][j]的边. (2) 对每个位置再建一个点F2,S向这个点连same_art[i][j]的边,这个点 ...

  7. BZOJ2127/LG1646 happiness 新建点最小割

    问题描述 BZOJ2127 LG1646 题解 和文理分科差不多 收益最大 -> 损失最小 -> 最小割 分别新建点表示互相关系就行了 \(\mathrm{Code}\) #include ...

  8. 【BZOJ3894】文理分科(最小割)

    [BZOJ3894]文理分科(最小割) 题面 BZOJ Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠 结过) 小P所在的班级要进行文理分科.他的班级可以用一个 ...

  9. 【bzoj3894】文理分科 网络流最小割

    原文地址:http://www.cnblogs.com/GXZlegend 题目描述 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用 ...

随机推荐

  1. SpringBoot项目的mybatis逆向工程

    <dependencies> <!--mybatis--> <dependency> <groupId>org.mybatis.spring.boot& ...

  2. 数据库——DBUtils和连接池

    第一章 DBUtils如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils.DBUtils就是JDBC的简 ...

  3. Compute和Linq的Field使用

    目录: Compute的使用 Field的使用 1.Compute 案例: private void ComputeBySalesSalesID(DataSet dataSet) { // Presu ...

  4. ListView常用属性 (2012-01-12 17:20:27)

    比较特别的属性,通过设置这样的属性可以做出更加美观的列表.stackFromBottom——设置该属性之后你最新条目就会显示你列表的最下面,值为true和false,如android:stackFro ...

  5. eclipse 中为 java 项目生成 API 文档、JavaDoc

    当我们的项目很大,编写了很多代码的时候,就需要生成一个标准的 API 文档,让后续的开发人员,或者合作者可以清晰的了解您方法的使用. 1.点击 eclipse 的 Project 菜单,选择 Gene ...

  6. 验证DNS解析失败:解决办法之一

    今天晚上练习简单的DNS解析验证: 环境是在一台虚拟机上搭建,另一台虚拟机验证,步骤如下: 虚拟机A: 1.安装软件包 bind  和bind-chroot[root@svr7 ~]# yum -y ...

  7. 求数组差/交集函数-php数组函数(二)

    求数组差集函数 函数只检查了多维数组中的一维.可以用 array_diff($array1[0], $array2[0]) 检查更深的维度. u:自定义函数比较,a(association):同时比较 ...

  8. JS权威指南笔记1

    1.JavaScript数据类型可分为两种:原始类型和对象类型.原始类型下又包括数字.字符串和布尔值,以及null和undefined这两个特殊的:对象是属性的集合,且每个属性都有自己的"名 ...

  9. idea 编译级别的设置

    File->Settings Project Structure

  10. 使用nfs3将hdfs挂载到本地或远程目录(非kerberos适用)

    最基本的配置方法,aix.kerberos等的操作详见http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/Hdf ...