zoukankan      html  css  js  c++  java
  • hdu 3667(拆边+最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667

    思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式。具体的拆边方法为:第i次取这条路时费用为(2*i-1)*a (i<=5),每条边的容量为1。如果这条边通过的流量为x,那正好sigma(2*i-1)(1<<i<<x)==x^2。然后就是跑最小费用最大流了。

      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 MAXM 22222222
      9 #define inf 1<<30
     10 
     11 struct Edge{
     12     int v,cap,cost,next;
     13 }edge[MAXM];
     14 
     15 int n,m,k,NE;
     16 int head[MAXN];
     17 
     18 void Insert(int u,int v,int cap,int cost)
     19 {
     20     edge[NE].v=v;
     21     edge[NE].cap=cap;
     22     edge[NE].cost=cost;
     23     edge[NE].next=head[u];
     24     head[u]=NE++;
     25 
     26     edge[NE].v=u;
     27     edge[NE].cap=0;
     28     edge[NE].cost=-cost;
     29     edge[NE].next=head[v];
     30     head[v]=NE++;
     31 }
     32 
     33 int dist[MAXN];
     34 bool mark[MAXN];
     35 int cur[MAXN],pre[MAXN];
     36 bool spfa(int vs,int vt)
     37 {
     38     memset(mark,false,sizeof(mark));
     39     fill(dist,dist+n+1,inf);
     40     dist[vs]=0;
     41     queue<int>que;
     42     que.push(vs);
     43     while(!que.empty()){
     44         int u=que.front();
     45         que.pop();
     46         mark[u]=false;
     47         for(int i=head[u];i!=-1;i=edge[i].next){
     48             int v=edge[i].v,cost=edge[i].cost;
     49             if(edge[i].cap>0&&dist[u]+cost<dist[v]){
     50                 dist[v]=dist[u]+cost;
     51                 pre[v]=u;
     52                 cur[v]=i;
     53                 if(!mark[v]){
     54                     mark[v]=true;
     55                     que.push(v);
     56                 }
     57             }
     58         }
     59     }
     60     return dist[vt]<inf;
     61 }
     62 
     63 int MinCostFlow(int vs,int vt)
     64 {
     65     int cost=0,flow=0;
     66     while(spfa(vs,vt)){
     67         int aug=inf;
     68         for(int u=vt;u!=vs;u=pre[u]){
     69             aug=min(aug,edge[cur[u]].cap);
     70         }
     71         flow+=aug;cost+=dist[vt]*aug;
     72         for(int u=vt;u!=vs;u=pre[u]){
     73             edge[cur[u]].cap-=aug;
     74             edge[cur[u]^1].cap+=aug;
     75         }
     76     }
     77     if(flow<k)cost=-1;
     78     return cost;
     79 }
     80 
     81 int main()
     82 {
     83     int u,v,cost,cap;
     84     while(~scanf("%d%d%d",&n,&m,&k)){
     85         NE=0;
     86         memset(head,-1,sizeof(head));
     87         while(m--){
     88             scanf("%d%d%d%d",&u,&v,&cost,&cap);
     89             for(int i=1;i<=cap;i++){
     90                 Insert(u,v,1,(2*i-1)*cost);
     91             }
     92         }
     93         Insert(0,1,k,0);
     94         printf("%d
    ",MinCostFlow(0,n));
     95     }
     96     return 0;
     97 }
     98 
     99 
    100 
    101         
    View Code
  • 相关阅读:
    Two Sum II
    Subarray Sum
    Intersection of Two Arrays
    Reorder List
    Convert Sorted List to Binary Search Tree
    Remove Duplicates from Sorted List II
    Partition List
    Linked List Cycle II
    Sort List
    struts2结果跳转和参数获取
  • 原文地址:https://www.cnblogs.com/wally/p/3307312.html
Copyright © 2011-2022 走看看