zoukankan      html  css  js  c++  java
  • [BZOJ1061][Noi2008]志愿者招募 线性规划+费用流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1061

    根据题意列方程,然后用网络流解线性规划。

    题解直接贴ByVoid的吧,太神了:https://www.byvoid.com/blog/noi-2008-employee/

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 using namespace std;
     6 const int INF=1<<30;
     7 int inline readint(){
     8     int Num;char ch;
     9     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
    10     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
    11     return Num;
    12 }
    13 int n,m;
    14 int A[1010];
    15 int S,T;
    16 int to[30000],ne[30000],w[30000],c[30000],fir[1010],cnt=0;
    17 void add(int a,int b,int x,int y=INF){
    18     to[cnt]=b,w[cnt]=x,c[cnt]=y,ne[cnt]=fir[a],fir[a]=cnt++;
    19     to[cnt]=a,w[cnt]=-x,c[cnt]=0,ne[cnt]=fir[b],fir[b]=cnt++;
    20 }
    21 int dis[1010],pre[1010];
    22 bool in[1010];
    23 queue <int> q;
    24 bool Spfa(){
    25     memset(dis,127/3,sizeof(dis));
    26     q.push(S);
    27     in[S]=true;
    28     dis[S]=0;
    29     int u;
    30     while(!q.empty()){
    31         u=q.front();
    32         q.pop();
    33         in[u]=false;
    34         for(int i=fir[u];i!=-1;i=ne[i]){
    35             int v=to[i];
    36             if(dis[v]>dis[u]+w[i]&&c[i]){
    37                 dis[v]=dis[u]+w[i];
    38                 pre[v]=i;
    39                 if(!in[v]){
    40                     q.push(v);
    41                     in[v]=true;
    42                 }
    43             }
    44         }
    45     }
    46     return dis[T]!=dis[0];
    47 }
    48 void Mcmf(){
    49     int cost=0;
    50     pre[S]=-1;
    51     while(Spfa()){
    52         int f=INF;
    53         for(int i=pre[T];i!=-1;i=pre[to[i^1]]) f=min(f,c[i]);
    54         for(int i=pre[T];i!=-1;i=pre[to[i^1]]){
    55             c[i]-=f;
    56             c[i^1]+=f;
    57         }
    58         cost+=dis[T]*f;
    59     }
    60     printf("%d
    ",cost);
    61 }
    62 int main(){
    63     n=readint();
    64     m=readint();
    65     for(int i=1;i<=n;i++) A[i]=readint();
    66     memset(fir,-1,sizeof(fir));
    67     S=n+2;
    68     T=n+3;
    69     for(int i=1;i<=n+1;i++){
    70         if(A[i]>=A[i-1]) add(S,i,0,A[i]-A[i-1]);
    71         else add(i,T,0,A[i-1]-A[i]);
    72         if(i>1) add(i,i-1,0);
    73     }
    74     for(int i=1;i<=m;i++){
    75         int a=readint(),
    76             b=readint(),
    77             c=readint();
    78         add(a,b+1,c);
    79     }
    80     Mcmf();
    81     return 0;
    82 }
  • 相关阅读:
    Android 编程下 Eclipse 恢复被删除的文件
    Android 编程下背景图片适配工具类
    Android 编程下 Managing Your App's Memory
    Android 编程下代码之(QQ消息列表滑动删除)
    Android 编程下 Canvas and Drawables
    Android 编程下 AlarmManager
    Android 编程下去除 ListView 上下边界蓝色或黄色阴影
    Java 编程下字符串的 16 位、32位 MD5 加密
    C#枚举类型和int类型相互转换
    MVC和普通三层架构的区别
  • 原文地址:https://www.cnblogs.com/halfrot/p/7553082.html
Copyright © 2011-2022 走看看