zoukankan      html  css  js  c++  java
  • [haoi2010]订货 最小费用流

    这道题oj上的标签是动态规划,但我想不出来动态规划怎么搞,空间不爆,时间也要爆的;

    好的,不扯淡,此题正常做法是最小费用流;

    这道题我写了两遍,为什么呢?原因是第一次写的时候,不会写费用流,又恰好没带书,所以搁置了;

    第二次又写到这道题了,有点生气,一鼓作气学了费用流,紧跟着敲了这道题;

    也算一道费用流模板吧;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<string>
     6 using namespace std;
     7 const int maxn=500;
     8 const int inf=10000000;
     9 const int S=0,T=50+1;
    10 struct node{
    11     int x,y,next,flow,v,re;
    12 }e[maxn];
    13 int linkk[maxn],len=0,n,m,s,u[maxn],c[maxn];
    14 void insert(int x,int y,int flow,int v){
    15     e[++len].x=x;
    16     e[len].y=y;
    17     e[len].v=v;
    18     e[len].flow=flow;
    19     e[len].next=linkk[x];
    20     e[len].re=len+1;
    21     linkk[x]=len;
    22     e[++len].x=y;
    23     e[len].y=x;
    24     e[len].flow=0;
    25     e[len].v=v;
    26     e[len].next=linkk[y];
    27     e[len].re=len-1;
    28     linkk[y]=len;
    29 }
    30 void init(){
    31     scanf("%d%d%d",&n,&m,&s);
    32     for(int i=1;i<=n;i++)scanf("%d",&u[i]);
    33     for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    34     for(int i=1;i<=n;i++){
    35         insert(S,i,inf,c[i]);insert(i,T,u[i],0);
    36     }
    37     for(int i=1;i<n;i++)insert(i,i+1,s,m);
    38 }
    39 int vis[maxn],d[maxn],q[maxn*maxn],head=0,tail=0,pre[maxn],ans=0,cap[maxn],t[maxn];
    40 bool SPFA(){
    41     for(int i=S;i<=T;i++)d[i]=inf<<2;
    42     memset(vis,0,sizeof(vis));
    43     head=0,tail=0;
    44     q[++tail]=S;d[S]=0;
    45     while(++head<=tail){
    46         int x=q[head];
    47         vis[x]=0;
    48         for(int i=linkk[x];i;i=e[i].next){
    49             if(e[i].flow&&d[e[i].y]>d[x]+e[i].v){
    50                 d[e[i].y]=d[x]+e[i].v;
    51                 cap[e[i].y]=e[i].flow;
    52                 t[e[i].y]=i;
    53                 pre[e[i].y]=x;
    54                 if(!vis[e[i].y]){
    55                     vis[e[i].y]=1;
    56                     q[++tail]=e[i].y;
    57                 }
    58             }
    59         }
    60     }
    61     if(d[T]==inf<<2)return 0;
    62     int flow=inf;
    63     for(int i=T;i!=S;i=pre[i])flow=min(flow,cap[i]);
    64     for(int i=T;i!=S;i=pre[i]){
    65         e[t[i]].flow-=flow;
    66         e[e[t[i]].re].flow+=flow;
    67         ans+=e[t[i]].v*flow;
    68     }
    69     return 1;
    70 }
    71 void work(){
    72     ans=0;
    73     while(SPFA());
    74     cout<<ans<<endl;
    75 }
    76 int main(){
    77     init();
    78     work();
    79 }
    View Code
  • 相关阅读:
    C++模板元编程(二)
    C++模板元编程(一)
    interpret_cast
    Bresenham算法
    Windows中编译Lua源码
    MathJax基础教程与快速参考
    散列表
    Bash脚本实例
    Bash基础
    【iOS】重读《精通Objective-C》(一)
  • 原文地址:https://www.cnblogs.com/chadinblog/p/5856156.html
Copyright © 2011-2022 走看看