bzoj 3996 最小割

公式推出来后想了半天没思路,居然A是01矩阵。。。。。

如果一个问题是求最值,并那么尝试先将所有可能收益加起来,然后矛盾部分能否用最小割表达(本题有两个矛盾,第一个是选还是不选,第二个是i,j有一个不选,就不能获得bij的收益)。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <vector>
  4 #define N 510
  5 #define S N+N*N
  6 #define E S*10
  7 #define oo 0x3f3f3f3f
  8 #define fill(a,l,r,v) memset(a+l,v,sizeof(a[0])*(r-l+1))
  9 using namespace std;
 10
 11 struct Edge {
 12     int u, v, f;
 13     Edge(){}
 14     Edge( int u, int v, int f ):u(u),v(v),f(f){}
 15 };
 16 struct Dinic {
 17     int n, src, dst;
 18     int head[S], next[E], etot;
 19     Edge edge[E];
 20     int dep[S], cur[S], qu[S], bg, ed;
 21
 22     void init( int n, int src, int dst ) {
 23         this->n = n;
 24         this->src = src;
 25         this->dst = dst;
 26         fill( head, 0, n, 0x3f );
 27     }
 28     void adde( int u, int v, int f ) {
 29         next[etot]=head[u], head[u]=etot;
 30         edge[etot++] = Edge(u,v,f);
 31         next[etot]=head[v], head[v]=etot;
 32         edge[etot++] = Edge(v,u,0);
 33     }
 34     bool bfs() {
 35         fill(dep,0,n,0);
 36         qu[bg=ed=1] = src;
 37         dep[src] = 1;
 38         while( bg<=ed ) {
 39             int u=qu[bg++];
 40             for( int t=head[u]; t!=oo; t=next[t] ) {
 41                 Edge &e = edge[t];
 42                 if( e.f && !dep[e.v] ) {
 43                     qu[++ed] = e.v;
 44                     dep[e.v] = dep[e.u]+1;
 45                 }
 46             }
 47         }
 48         return dep[dst];
 49     }
 50     int dfs( int u, int a ) {
 51         if( u==dst || a==0 ) return a;
 52         int remain=a, past=0, na;
 53         if( cur[u]==-1 ) cur[u]=head[u];
 54         for( int &t=cur[u]; t!=oo; t=next[t] ) {
 55             Edge &e = edge[t];
 56             Edge &ve = edge[t^1];
 57             if( e.f && dep[e.v]==dep[e.u]+1 && (na=dfs(e.v,min(e.f,remain))) ) {
 58                 remain -= na;
 59                 past += na;
 60                 e.f -= na;
 61                 ve.f += na;
 62                 if( !remain ) break;
 63             }
 64         }
 65         return past;
 66     }
 67     int flow() {
 68         int rt = 0;
 69         while( bfs() ) {
 70             fill( cur, 0, n, -1 );
 71             rt += dfs(src,oo);
 72         }
 73         return rt;
 74     }
 75 }D;
 76
 77 int n, src, dst, idc;
 78 int main() {
 79     scanf( "%d", &n );
 80     src = 0;
 81     dst = n*n+n+1;
 82     idc = 0;
 83     D.init( dst, src, dst );
 84     int tot=0;
 85     for( int i=1; i<=n; i++ )
 86         for( int j=1; j<=n; j++ ) {
 87             int bij;
 88             scanf( "%d", &bij );
 89             idc++;
 90             D.adde( src, idc, bij );
 91             D.adde( idc, i, oo );
 92             D.adde( idc, j, oo );
 93             tot += bij;
 94         }
 95     for( int i=1; i<=n; i++ ) {
 96         int ci;
 97         scanf( "%d", &ci );
 98         D.adde( src, i, 0 );
 99         D.adde( i, dst, ci );
100     }
101     printf( "%d\n", tot-D.flow() );
102 }

——————

我的最小割好慢。。。

时间: 2024-09-30 11:14:30

bzoj 3996 最小割的相关文章

BZOJ 1797 最小割

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1797 题意:给出一个有向图,每条边有流量,给出源点汇点s.t.对于每条边,询问:(1)是否存在一个最小割包含该边?(2)是否所有的最小割都包含该边? 思路:首先求最大流,在残余网络中求强连通 分量.对于每条原图中的边(最大流中添加的反向边不算)<u,v>,该边的残余流量为0且u和v在两个不同的强连通分量中,则存在一个最小割 包含该边:在上述满足且u与s在一个连通分量.v与t在一个连通

BZOJ - 1497 最小割应用

题意:基站耗费成本,用户获得利益(前提是投入成本),求最大获利 最小割的简单应用,所有可能的收益-(消耗的成本/失去的收益),无穷大边表示冲突,最小割求括号内的范围即可 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<string> #in

BZOJ 2229 最小割

谁会像我一样把INF设成0x3f? GH Tree. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define maxv 250 #define maxe 50050 #define inf 0x7fffffff using namespace std; struct edge { int v,f,nxt; }

bzoj 3275 最小割

给你一堆东西,叫你选一些东西出来,使得价值最大,要求选出的东西集合中的任意a,b满足性质p. 可以考虑: 1.拟阵? 2.二分图? 这道题由于数学硬伤,不知道不存在两条直角边是奇数,斜边是整数的直角三角形. 证明是: 对于奇数a: a*a = 1 mod 4 对于偶数a: a*a = 0 mod 4 所以对于两个奇数a,b: a*a+b*b = 2 mod 4 不存在整数c使得: a*a+b*b = c*c mod 4 1 /***********************************

BZOJ 1266 上学路线route(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1266 题意:给出一个无向图,每条边有长度和代价.求出1到n的最短路.之后删掉一些边使得1到n的最短路变大?在此情况下使得删掉边的代价之和最小. 思路:首先求出每个点到1和n的最短路.之后可以确定每条边是否为关键边(就是最短路上的边).将关键边建立网络流图,求最小割即可. struct node { int v,cap,next; }; node edges[N]; int head[N

BZOJ 2007 海拔(平面图最小割-最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2007 题意:给出一个n*n的格子,那么顶点显然有(n+1)*(n+1)个.每两个相邻顶点之间有两条边,这两条边是有向的,边上有权值..左上角为源点,右下角为汇点,求s到t的最小割. 思路:很明显这是一个平面图,将其转化为最 短路.我们将s到t之间连一条边,左下角为新图的源点S,右上角区域为新图的终点T,并且为每个格子编号.由于边是有向的,我们就要分析下这条边应该是哪 个点向哪个点的边.

BZOJ 1976 能量魔方 Cube(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1976 题意:给出一个n*n*n的立方体.每个小单位为字母P或者字母N.相邻两个小单位字母不同则总价值加1.现在有些小单位的字母已经确定,合理安排其他小单位的字母使得总价值最大? 思路:显然,若所有小单位都未确定,则进 行黑白染色即PN相间的安排时价值最大.基于这样的考虑,我们将所有小单位分成黑白两种颜色,设为A和B.显然同一种颜色之间是不会相邻的.设S集合为A 集合中的P(就是已经给出

BZOJ 2132 圈地计划(最小割)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2132 题意:n*m的格子染色黑白,对于格子(i,j)染黑色则价值为A[i][j],白色为B[i][j].若一个格子四周不同颜色的有x个,则额外的价值为x*C[i][j].求最大价值. 思路:将格子黑白染色分成两个集合X和Y.S集合为X中的A和Y中的B,T为X中的B和Y中的A.相邻的连边为两个格子的C值之和.总权值减去最小割即是答案. struct node { int v,cap,ne

bzoj 1497 最大获利 - 最小割

新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战.THU集团旗下的CS&T通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究.站址勘测.最优化等项目.在前期市场调查和站址勘测之后,公司得到了一共N个可以作为通讯信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第i个通讯中转站需要的成本为Pi(1≤i≤N).另外公司调查得出了所有期望中的