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 }
View Code

——————

我的最小割好慢。。。

posted @ 2015-05-24 11:52  idy002  阅读(131)  评论(0编辑  收藏  举报