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

    Transportation

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2301    Accepted Submission(s): 966


    Problem Description
    There are N cities, and M directed roads connecting them. Now you want to transport K units of goods from city 1 to city N. There are many robbers on the road, so you must be very careful. The more goods you carry, the more dangerous it is. To be more specific, for each road i, there is a coefficient ai. If you want to carry x units of goods along this road, you should pay ai * x2 dollars to hire guards to protect your goods. And what’s worse, for each road i, there is an upper bound Ci, which means that you cannot transport more than Ci units of goods along this road. Please note you can only carry integral unit of goods along each road.
    You should find out the minimum cost to transport all the goods safely. 
     
    Input
    There are several test cases. The first line of each case contains three integers, N, M and K. (1 <= N <= 100, 1 <= M <= 5000, 0 <= K <= 100). Then M lines followed, each contains four integers (ui, vi, ai, Ci), indicating there is a directed road from city ui to vi, whose coefficient is ai and upper bound is Ci. (1 <= ui, vi <= N, 0 < ai <= 100, Ci <= 5)
     
    Output
    Output one line for each test case, indicating the minimum cost. If it is impossible to transport all the K units of goods, output -1.

     
    Sample Input
    2 1 2 1 2 1 2 2 1 2 1 2 1 1 2 2 2 1 2 1 2 1 2 2 2
     
    Sample Output
    4 -1 3
    这题的重点是拆边,虽然之前没见过拆边的题目,但是这提这么简单的思路我竟然没想到,还是该给自己一个大耳光
     
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<queue>
      4 #include<cstring>
      5 #include<climits>
      6 #define MAXP 110
      7 #define MAXE 51000
      8 using namespace std;
      9 struct Edge
     10 {
     11     int s,t,f,c,next;
     12 } edge[MAXE];
     13 int head[MAXP];
     14 int pre[MAXP];
     15 int dist[MAXP];
     16 bool isq[MAXP];
     17 int n,m,k,s,t,u,v,c,f,ent;
     18 void add(int S,int T,int f,int c)
     19 {
     20     edge[ent].s=S;
     21     edge[ent].t=T;
     22     edge[ent].f=f;
     23     edge[ent].c=c;
     24     edge[ent].next=head[S];
     25     head[S]=ent++;
     26     edge[ent].s=T;
     27     edge[ent].t=S;
     28     edge[ent].f=0;
     29     edge[ent].c=-c;
     30     edge[ent].next=head[T];
     31     head[T]=ent++;
     32 }
     33 int MIN(int a,int b)
     34 {
     35     return a<b?a:b;
     36 }
     37 bool spfa()
     38 {
     39     memset(pre,-1,sizeof(pre));//初始化路径为-1
     40     for(int i=s; i<=t; i++)
     41     {
     42         isq[i]=false;//每点开始时均不在队列里面
     43         dist[i]=INT_MAX;//初始化到每点的最小费用均为INT_MAX
     44     }
     45     queue<int>q;
     46     q.push(s);
     47     isq[s]=true;//源点s已经放入到队列里面去了
     48     dist[s]=0;//从源点到源点的距离为0
     49     while(!q.empty())//当队列为空时优化过程结束,退出循环
     50     {
     51         int temp1=q.front();
     52         q.pop();
     53         isq[temp1]=false;//该点已经退出队列
     54         for(int i=head[temp1]; i!=-1; i=edge[i].next) //从该点找通过邻接表找所有的以该点为起点的边,从中找出能优化的点
     55         {
     56             int temp2=edge[i].t;
     57             if(edge[i].f&&dist[temp2]>dist[temp1]+edge[i].c)
     58             {
     59                 dist[temp2]=dist[temp1]+edge[i].c;
     60                 pre[temp2]=i;
     61                 if(!isq[temp2])//如果该点不在队列中,则将该点放入队列中
     62                 {
     63                     q.push(temp2);
     64                     isq[temp2]=true;
     65                 }
     66             }
     67         }
     68     }
     69     return pre[t]!=-1;//如果pre[t]==-1的话说明没有找到从s到t的路径,即已经找到所有的路径了,结束循环
     70 }
     71 void mcmf()
     72 {
     73     int tot=0;
     74     int sum=0;
     75     int mincost=INT_MAX;
     76     int minn=INT_MAX;
     77     while(spfa())
     78     {
     79         tot++;
     80         mincost=dist[t];
     81         sum+=mincost;
     82         if(tot==k)
     83         {
     84             printf("%d
    ",sum);
     85             return;
     86         }
     87         for(int i=pre[t];i!=-1;i=pre[i])//最小费用最大流中的减流的过程
     88         {
     89             edge[i].f--;
     90             edge[i^1].f++;
     91             i=edge[i].s;
     92         }
     93     }
     94     printf("-1
    ");
     95 }
     96 int main()
     97 {
     98     while(~scanf("%d%d%d",&n,&m,&k))
     99     {
    100         ent=0;
    101         memset(head,-1,sizeof(head));
    102         s=1;t=n;
    103         for(int i=1;i<=m;i++)
    104         {
    105             scanf("%d%d%d%d",&u,&v,&c,&f);
    106             for(int j=1;j<=f;j++)
    107                 add(u,v,1,(j*2-1)*c);
    108         }
    109         if(m==0||n==1)
    110         {
    111             printf("0
    ");
    112             continue;
    113         }
    114         mcmf();
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    关于dubbo创建服务和引用服务时,会报错:cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 问题的解决
    解决 Maven工程运行报错Failed to clean project: Failed to delete
    Linux学习_004_使用CentOS 7.5卸载自带jdk安装自己的JDK1.8
    Linux下的JDK和OpenJDK有什么具体的区别
    常用的大数据技术有哪些?
    如何隐藏你的 Linux 的命令行历史
    Securi-Pi:使用树莓派作为安全跳板
    在 Linux 上管理加密密钥的最佳体验
    在 Linux 下使用任务管理器
    在 Linux 中安装 Lighttpd Web 服务器
  • 原文地址:https://www.cnblogs.com/lthb/p/4466953.html
Copyright © 2011-2022 走看看