zoukankan      html  css  js  c++  java
  • 「BZOJ2879」[Noi2012]美食节

    这道题就是 「BZOJ1070」[SCOI2007]修车 的加强版

    如果一开始把全部边连上会T

    优化的方法是只连用到过和下一次增广可能用到的边。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=50,M=110,NN=100010,oo=1e9;
     4 int n,m,cost[N][M],tot,s,t,p[N],rank[NN],c[NN];
     5 bool isend[NN];
     6 struct Edge{
     7     int from,to,flow,cap,w;
     8 };
     9 int edge_tot;
    10 vector<Edge>edge;
    11 vector<int>point[NN];
    12 void add_edge(int f,int t,int cc,int ww){
    13     edge.push_back((Edge){f,t,0,cc,ww});
    14     point[f].push_back(edge_tot++);
    15     edge.push_back((Edge){t,f,0,0,-ww});
    16     point[t].push_back(edge_tot++);
    17     return;
    18 }
    19 int dis[NN],pre[NN];
    20 bool inq[NN];
    21 bool spfa(){
    22     queue<int>q;
    23     int x;
    24     for(int i=1;i<=tot;i++) dis[i]=oo;
    25     q.push(s);
    26     dis[s]=0,inq[s]=1;
    27     while(!q.empty()){
    28         x=q.front();q.pop();
    29         inq[x]=0;
    30         for(int i=0;i<point[x].size();i++){
    31             Edge& e=edge[point[x][i]];
    32             if(e.cap<=e.flow) continue;
    33             if(dis[x]+e.w<dis[e.to]){
    34                 dis[e.to]=dis[x]+e.w,pre[e.to]=point[x][i];
    35                 if(!inq[e.to]){inq[e.to]=1;q.push(e.to);}
    36             }
    37         }
    38     }
    39     return dis[t]<oo;
    40 }
    41 int mincostmaxflow(){
    42     int ans=0,f,now;
    43     while(spfa()){
    44         f=oo,now=t;
    45         while(now!=s){
    46             f=min(f,edge[pre[now]].cap-edge[pre[now]].flow);
    47             if(isend[now]){
    48                 isend[now]=0,isend[++tot]=1,rank[tot]=rank[now]+1,c[tot]=c[now];
    49                 add_edge(tot,t,1,0);
    50                 for(int i=3;i<=n+2;i++) add_edge(i,tot,1,rank[tot]*cost[i-2][c[tot]]);
    51             }
    52             now=edge[pre[now]].from;
    53         }
    54         ans+=dis[t]*f,now=t;
    55         while(now!=s){
    56             edge[pre[now]].flow+=f,edge[pre[now]^1].flow-=f;
    57             now=edge[pre[now]].from;
    58         }
    59     }
    60     return ans;
    61 }
    62 int main(){
    63     scanf("%d%d",&n,&m);
    64     for(int i=1;i<=n;i++) scanf("%d",&p[i]);
    65     for(int i=1;i<=n;i++)
    66         for(int j=1;j<=m;j++)scanf("%d",&cost[i][j]);
    67     s=++tot,t=++tot;
    68     for(int i=1;i<=n;i++) add_edge(s,++tot,p[i],0);
    69     for(int i=1;i<=m;i++){
    70         add_edge(++tot,t,1,0);
    71         rank[tot]=1,c[tot]=i,isend[tot]=1;
    72         for(int j=3;j<=n+2;j++) add_edge(j,i+n+2,1,cost[j-2][i]);
    73     }
    74     int ans=mincostmaxflow();
    75     printf("%d",ans);
    76 }
  • 相关阅读:
    实数的构造
    实数的构造
    某曲线上的点到两点距离和最小的问题都可以用做椭圆解决
    Java 性能优化之 String 篇
    使用 Spring Data JPA 简化 JPA 开发
    使用 Sonar 进行代码质量管理
    Servlet运行周期与原理流程
    使用 Java 配置进行 Spring bean 管理
    通过日志监控并收集 Java 应用程序性能数据
    基于 JUnit 的全局单元测试程序
  • 原文地址:https://www.cnblogs.com/mycups/p/8528851.html
Copyright © 2011-2022 走看看