zoukankan      html  css  js  c++  java
  • 【BZOJ】【3894】文理分科

    网络流/最小割


      rausen大爷太神辣~作为一个蒟蒻还是搬运题解吧……

    很明显的一道网络流题。。

    首先把所有值的加起来,再减掉网络流最小割值就好了,问题就是如何建图。这貌似也是考了好多次了的。。。

    把每个人抽象成一个点p,则

    先是S向p连边,流量为选文科的高兴值,p向T连边,流量为选理科的高兴值。

    然后是same的条件,对每个人新建两个点p1, p2

    S向p1连边,流量为文科same的高兴值,p1向相邻点和自己的p连边,流量为inf

    p2相T连边,流量为理科same的高兴值,相邻点和自己的p向p2连边,流量为inf

    然后跑一下网络流就好了(蒟蒻tot = 1没写调了半天还以为建图错了= =b)

      1 /**************************************************************
      2     Problem: 3894
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:2404 ms
      7     Memory:40340 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 3894
     11 #include<vector>
     12 #include<cstdio>
     13 #include<cstring>
     14 #include<cstdlib>
     15 #include<iostream>
     16 #include<algorithm>
     17 #define rep(i,n) for(int i=0;i<n;++i)
     18 #define F(i,j,n) for(int i=j;i<=n;++i)
     19 #define D(i,j,n) for(int i=j;i>=n;--i)
     20 #define pb push_back
     21 using namespace std;
     22 inline int getint(){
     23     int v=0,sign=1; char ch=getchar();
     24     while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
     25     while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
     26     return v*sign;
     27 }
     28 const int N=1e6+10,M=2000010,INF=~0u>>2;
     29 typedef long long LL;
     30 /******************tamplate*********************/
     31 const int fx[]={0,1,0,-1,0},
     32           fy[]={1,0,-1,0,0};
     33 int n,m,tot,ans;
     34 struct edge{int to,v;};
     35 inline int pack(int i,int j){return (i-1)*m+j;}
     36 #define FOR F(i,1,n)F(j,1,m)
     37 struct Net{
     38     edge E[M];
     39     int head[N],next[M],cnt;
     40     void ins(int x,int y,int v){
     41         E[++cnt]=(edge){y,v};
     42         next[cnt]=head[x]; head[x]=cnt;
     43     }
     44     void add(int x,int y,int v){
     45         ins(x,y,v); ins(y,x,0);
     46     }
     47     int s,t,cur[N],d[N],Q[N];
     48     bool mklevel(){
     49         memset(d,-1,sizeof d);
     50         d[s]=0;
     51         int l=0,r=-1;
     52         Q[++r]=s;
     53         while(l<=r){
     54             int x=Q[l++];
     55             for(int i=head[x];i;i=next[i])
     56                 if (d[E[i].to]==-1 && E[i].v){
     57                     d[E[i].to]=d[x]+1;
     58                     Q[++r]=E[i].to;
     59                 }
     60         }
     61         return d[t]!=-1;
     62     }
     63     int dfs(int x,int a){
     64         if (x==t) return a;
     65         int flow=0;
     66         for(int i=head[x];i && flow<a;i=next[i])
     67             if (E[i].v && d[E[i].to]==d[x]+1){
     68                 int f=dfs(E[i].to,min(a-flow,E[i].v));
     69                 E[i].v-=f;
     70                 E[i^1].v+=f;
     71                 flow+=f;
     72             }
     73         if (!flow) d[x]=-1;
     74         return flow;
     75     }
     76     void Dinic(){
     77         while(mklevel()) ans-=dfs(s,INF);
     78     }
     79     void init(){
     80         n=getint(); m=getint(); cnt=1;
     81         tot=n*m; s=0; t=tot*3+1;
     82         int x=0;
     83         FOR{
     84             x=getint(); ans+=x;
     85             add(s,pack(i,j),x);
     86         }
     87         FOR{
     88             x=getint(); ans+=x;
     89             add(pack(i,j),t,x);
     90         }
     91         FOR{
     92             x=getint(); ans+=x;
     93             add(s,tot+pack(i,j),x);
     94             F(k,0,4){
     95                 int tx=i+fx[k],ty=j+fy[k];
     96                 if(tx<1||ty<1||tx>n||ty>m)continue;
     97                 add(tot+pack(i,j),pack(tx,ty),INF);
     98             }
     99         }
    100         FOR{
    101             x=getint(); ans+=x;
    102             add(tot*2+pack(i,j),t,x);
    103             F(k,0,4){
    104                 int tx=i+fx[k],ty=j+fy[k];
    105                 if(tx<1||ty<1||tx>n||ty>m)continue;
    106                 add(pack(tx,ty),tot*2+pack(i,j),INF);
    107             }
    108         }
    109         Dinic();
    110         printf("%d
    ",ans);
    111     }
    112 }G1;
    113  
    114 int main(){
    115 #ifndef ONLINE_JUDGE
    116     freopen("3894.in","r",stdin);
    117     freopen("3894.out","w",stdout);
    118 #endif
    119     G1.init();
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    Git使用经验小结
    Git使用经验小结
    关于IT增值服务"拜师学艺"价格调整的通知
    关于IT增值服务"拜师学艺"价格调整的通知
    Java实现 LeetCode 397 整数替换
    Java实现 LeetCode 397 整数替换
    Java实现 LeetCode 397 整数替换
    Java实现 LeetCode 396 旋转函数
    Java实现 LeetCode 396 旋转函数
    Java实现 LeetCode 396 旋转函数
  • 原文地址:https://www.cnblogs.com/Tunix/p/4382476.html
Copyright © 2011-2022 走看看