zoukankan      html  css  js  c++  java
  • BZOJ 1449: [JSOI2009]球队收益 最小费用最大流 网络流

    https://www.lydsy.com/JudgeOnline/problem.php?id=1449

    给每条路加上一个权值,每条路的费用是这条路的流量*权值,求最大流的最小费用。

    每次spfa记录一下路径找最短的有流量的路,然后就是普通最大流的操作,反向边加流量什么的,网络流的作用依然是选择。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 #define LL long long
     9 const int maxn=6100;
    10 int n,m,S,E;
    11 int wi[maxn]={},lo[maxn]={},c[maxn]={},d[maxn]={},zz[maxn]={};
    12 struct nod{
    13     int x,y,co,v,rev,next;
    14 }e[maxn*2];
    15 int head[maxn]={},vis[maxn]={},tot=0,mx;
    16 void init(int x,int y,int v,int co,int rev){
    17     e[++tot].x=x;e[tot].y=y;e[tot].co=co;
    18     e[tot].v=v;e[tot].rev=rev;e[tot].next=head[x];head[x]=tot;
    19 }
    20 queue<int>q;
    21 int dis[maxn]={},fa[maxn]={};
    22 int spfa(){
    23     memset(vis,0,sizeof(vis));
    24     memset(dis,63,sizeof(dis));
    25     memset(fa,0,sizeof(fa));
    26     mx=dis[0];q.push(S);vis[S]=1;dis[S]=0;
    27     while(!q.empty()){
    28         int x=q.front();q.pop();vis[x]=0;
    29         for(int i=head[x];i;i=e[i].next){
    30             if(e[i].v){
    31                 if(dis[e[i].y]>dis[x]+e[i].co){
    32                     dis[e[i].y]=dis[x]+e[i].co;
    33                     fa[e[i].y]=i;
    34                     if(!vis[e[i].y]){
    35                         vis[e[i].y]=1;q.push(e[i].y);
    36                     }
    37                 }
    38             }
    39         }
    40     }
    41     return fa[E];
    42 }
    43 int fyl(){
    44     int ans=0,val=mx;
    45     for(int i=fa[E];i;i=fa[e[i].x])val=min(val,e[i].v);
    46     for(int i=fa[E];i;i=fa[e[i].x]){
    47         e[i].v-=val;e[e[i].rev].v+=val;ans+=val*e[i].co;
    48     }
    49     return ans;
    50 }
    51 int main(){
    52     scanf("%d%d",&n,&m);S=n+m+1;E=S+1;
    53     for(int i=1;i<=n;i++) scanf("%d%d%d%d",&wi[i],&lo[i],&c[i],&d[i]);
    54     int x,y;
    55     for(int i=1;i<=m;i++){
    56         scanf("%d%d",&x,&y);
    57         lo[x]++;lo[y]++;zz[x]++;zz[y]++;
    58         init(S,n+i,1,0,tot+2);init(n+i,S,0,0,tot);
    59         init(n+i,x,1,0,tot+2);init(x,n+i,0,0,tot);
    60         init(n+i,y,1,0,tot+2);init(y,n+i,0,0,tot);
    61     }
    62     int ans=0;
    63     for(int i=1;i<=n;i++){
    64         ans+=wi[i]*wi[i]*c[i]+lo[i]*lo[i]*d[i];
    65         for(int j=1;j<=zz[i];j++){
    66             int z=c[i]*(2*wi[i]+1)-d[i]*(2*lo[i]-1);
    67             init(i,E,1,z,tot+2);init(E,i,0,-z,tot);
    68             wi[i]++;lo[i]--;
    69         }
    70     }
    71     while(spfa())ans+=fyl();
    72     printf("%d
    ",ans);
    73     return 0;
    74 }
    View Code

  • 相关阅读:
    词云(WordCloud)
    Pandas常用方法
    PCA降维的原理及实现
    支持向量机(SVM)公式整理
    《小狗钱钱》
    初识 Netty
    hello world
    算法-归并排序
    算法-堆与堆排序
    Java并发编程05-线程池
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8862903.html
Copyright © 2011-2022 走看看