Double Shortest Paths(费用流)2014年省赛D题

来源:互联网 发布:压缩包软件 编辑:程序博客网 时间:2024/06/05 02:23

Problem D: Double Shortest Paths

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 255  Solved: 85
[Submit][Status][Web Board]

Description

Input

There will be at most 200 test cases. Each case begins with two integers n, m (1<=n<=500, 1<=m<=2000), the number of caves and passages. Each of the following m lines contains four integers u, v, di and ai (1<=u,v<=n, 1<=di<=1000, 0<=ai<=1000). Note that there can be multiple passages connecting the same pair of caves, and even passages connecting a cave and itself.

Output

For each test case, print the case number and the minimal total difficulty.

Sample Input

4 41 2 5 12 4 6 01 3 4 03 4 9 14 41 2 5 102 4 6 101 3 4 103 4 9 10

Sample Output

Case 1: 23Case 2: 24

HINT

/*最小费用最大流:求最大费用只需费用cost取反,结果取反即可。算法思想:先用spfa找一条最小费用的可增广流路径,再更新残流网络,数组模拟队列快存图:邻接表*/#include<stdio.h>#include<string.h>#include<queue>using namespace std;const int MAXN = 510;const int MAXM = 100100;const int INF = 1<<30;struct EDG{    int to,next,cap,flow;    int cost;  //单价}edg[MAXM];int head[MAXN],eid;int pre[MAXN], cost[MAXN] ; //点0~(n-1)void init(){    eid=0;    memset(head,-1,sizeof(head));}void addEdg(int u,int v,int cap,int cst){    edg[eid].to=v; edg[eid].next=head[u]; edg[eid].cost = cst;    edg[eid].cap=cap; edg[eid].flow=0; head[u]=eid++;    edg[eid].to=u; edg[eid].next=head[v]; edg[eid].cost = -cst;    edg[eid].cap=0; edg[eid].flow=0; head[v]=eid++;}bool inq[MAXN];int q[MAXN];bool spfa(int sNode,int eNode,int n){    int l=0 , r=0;    for(int i=0; i<=n; i++){        inq[i]=false; cost[i]= INF;    }    cost[sNode]=0; inq[sNode]=1; pre[sNode]=-1;    q[r++]=sNode;    while(l!=r){        int u=q[l++];        if(l==MAXN)l=0;        inq[u]=0;        for(int i=head[u]; i!=-1; i=edg[i].next){            int v=edg[i].to;            if(edg[i].cap-edg[i].flow>0 && cost[v]>cost[u]+edg[i].cost){ //在满足可增流的情况下,最小花费                cost[v] = cost[u]+edg[i].cost;                pre[v]=i;   //记录路径上的边                if(!inq[v]){                    if(r==MAXN)r=0;                    q[r++]=v;                    inq[v]=1;                }            }        }    }    return cost[eNode]!=INF;    //判断有没有增广路}//反回的是最大流,最小花费为minCostint minCost_maxFlow(int sNode,int eNode ,int& minCost,int n){    int ans=0 ;    while(spfa(sNode,eNode,n)){        int mint=INF;        for(int i=pre[eNode]; i!=-1; i=pre[edg[i^1].to]){            if(mint>edg[i].cap-edg[i].flow)                mint=edg[i].cap-edg[i].flow;        }        ans+=mint;        for(int i=pre[eNode]; i!=-1; i=pre[edg[i^1].to]){            edg[i].flow+=mint; edg[i^1].flow-=mint;            minCost+=mint*edg[i].cost;        }        if(ans==2)break;    }    return ans;}int main(){    //输入,初始化init()    int n,m,u,v,d,a;    int T=0;    while(scanf("%d%d",&n,&m)>0)    {        init();        while(m--)        {            scanf("%d%d%d%d",&u,&v,&d,&a);            addEdg(u , v , 1 , d);            addEdg(u , v , 1 , d+a);        }        int ans=0;        minCost_maxFlow(1 , n , ans, n);        printf("Case %d: %d\n",++T , ans);    }}


0 0
原创粉丝点击