zoukankan      html  css  js  c++  java
  • zoj 3362(最大费用)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3904

    思路:费用流的题,增加一个超级源点和一个超级汇点,然后就是连边了,对于每个城市,与汇点连边,容量为inf,花费(这里指收益)为商品在该城市的价值,然后对于图中给定的边,容量为cap,花费为-cost(负数代表花费),最后就是源点与城市1连边了,然后就是跑费用流了,求最大收益(当dist[vt]<0时直接退出)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 #define MAXN 222
     8 #define inf 1<<30
     9 
    10 struct Edge{
    11     int v,cap,cost,next;
    12 }edge[MAXN*MAXN];
    13 
    14 int n,m,vs,vt,NE;
    15 int head[MAXN];
    16 
    17 void Insert(int u,int v,int cap,int cost)
    18 {
    19     edge[NE].v=v;
    20     edge[NE].cap=cap;
    21     edge[NE].cost=cost;
    22     edge[NE].next=head[u];
    23     head[u]=NE++;
    24 
    25     edge[NE].v=u;
    26     edge[NE].cap=0;
    27     edge[NE].cost=-cost;
    28     edge[NE].next=head[v];
    29     head[v]=NE++;
    30 }
    31 
    32 bool mark[MAXN];
    33 int dist[MAXN],pre[MAXN],cur[MAXN];
    34 bool spfa(int vs,int vt)
    35 {
    36     memset(mark,false,sizeof(mark));
    37     fill(dist,dist+MAXN,-inf);
    38     dist[vs]=0;
    39     queue<int>que;
    40     que.push(vs);
    41     while(!que.empty()){
    42         int u=que.front();
    43         que.pop();
    44         mark[u]=false;
    45         for(int i=head[u];i!=-1;i=edge[i].next){
    46             int v=edge[i].v,cost=edge[i].cost;
    47             if(edge[i].cap>0&&dist[u]+cost>dist[v]){
    48                 dist[v]=dist[u]+cost;
    49                 pre[v]=u;
    50                 cur[v]=i;
    51                 if(!mark[v]){
    52                     mark[v]=true;
    53                     que.push(v);
    54                 }
    55             }
    56         }
    57     }
    58     return dist[vt]>0;
    59 }
    60 
    61 int MinCostFlow(int vs,int vt)
    62 {
    63     int flow=0,cost=0;
    64     while(spfa(vs,vt)){
    65         int aug=inf;
    66         for(int u=vt;u!=vs;u=pre[u]){
    67             aug=min(aug,edge[cur[u]].cap);
    68         }
    69         flow+=aug,cost+=aug*dist[vt];
    70         for(int u=vt;u!=vs;u=pre[u]){
    71             edge[cur[u]].cap-=aug;
    72             edge[cur[u]^1].cap+=aug;
    73         }
    74     }
    75     return cost;
    76 }
    77 
    78 int main()
    79 {
    80     int x,u,v,cap,cost;
    81     while(~scanf("%d%d",&n,&m)){
    82         vs=0,vt=n+1;
    83         NE=0;
    84         memset(head,-1,sizeof(head));
    85         for(int i=2;i<=n;i++){
    86             scanf("%d",&x);
    87             Insert(i,vt,inf,x);
    88         }
    89         while(m--){
    90             scanf("%d%d%d%d",&u,&v,&cap,&cost);
    91             Insert(u,v,cap,-cost);
    92             Insert(v,u,cap,-cost);
    93         }
    94         Insert(vs,1,inf,0);
    95         printf("%d
    ",MinCostFlow(vs,vt));
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    多个网站域名使用同一个IP的设置
    Delphi 文本文件操作
    iframe 元素
    ssis 配置 sqlserver 作业
    关闭占用端口号的进程
    如果你知道要往哪里去,全世界都会给你让路
    不再消极,不再忧虑
    bat 拷贝文件并记录日志
    添加 aspnet 账户到共享文件夹
    截止2013年5月,.net 所有技术路线的一个概括
  • 原文地址:https://www.cnblogs.com/wally/p/3325057.html
Copyright © 2011-2022 走看看