Double Shortest Paths 网络流

来源:互联网 发布:手机淘宝评论怎么截图 编辑:程序博客网 时间:2024/06/05 06:37

题目:

Problem D. Double Shortest Paths  

Alice and Bob are walking in an ancient maze with a lot of caves and one-way passages connecting them. They want to go from cave 1 to cave n. All the passages are difficult to pass. Passages are too small for two people to walk through simultaneously, and crossing a passage can make it even more difficult to pass for the next person. We define di as the difficulty of crossing passage i for the first time, and ai as the additional difficulty for the second time (e.g. the second person's difficulty is di+ai).  

Your task is to find two (possibly identical) routes for Alice and Bob, so that their total difficulty is minimized.    

For example, in figure 1, the best solution is 1->2->4 for both Alice and Bob, but in figure 2, it's better to use 1->2->4 for Alice and 1->3->4 for Bob.  

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            

Output for Sample Input 

4 4

 1 2 5 1

 2 4 6 0

 1 3 4 0

 3 4 9 1

 4 4

 1 2 5 10

 2 4 6 10

 1 3 4 10 

3 4 9 10

Case 1: 23 

Case 2: 24 

题目大意:

从一走到n求走两次最小费用,如果是第二次走到该点,费用会增加。

题目思路:

 

1、题目和uva 10806 Dijkstra, Dijkstra. 很像

2、第一次可以用dijlstra算法,然后网络流增流,然后用flow算法

3、增流的时候要给路径加上附加值

4、.增流不要删掉之前的路。

程序:

 

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <queue>#include <stack>#include <map>#include <cmath>#include <string>#define INF 0x3f3f3f3fusing namespace std;struct street{    int x,y,f,d;} a[2100];bool vv[1000];int n,m;int v[1000];int dij();int dfs(int);int main(){    int ci=1;    while(~scanf("%d%d",&n,&m))    {        memset(vv,0,sizeof(vv));        int ans=0;        for(int i=0; i<m; i++)//cout<<'#';            scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].f,&a[i].d);        ans+=dij();        dfs(n);        ans+=dij();        printf("Case %d: %d\n",ci++,ans);    }    return 0;}int dij(){    memset(v,INF,sizeof(v));    v[1]=0;    for(int i=0; i<n; i++)        for(int j=0; j<m; j++)            if(v[a[j].x]!=INF)            v[a[j].y]=min(v[a[j].y],v[a[j].x]+a[j].f);    return v[n];}int dfs(int dian){    if(dian==1)        return 1;    for(int i=0; i<m; i++)    {        if(a[i].y==dian)            if(!vv[a[i].x])                //if(!vv[a[i].y])                if(v[a[i].y]-v[a[i].x]==a[i].f)                {                    vv[a[i].x]=1;                    int t=m;                    m++;                    a[t].x=a[i].y;                    a[t].y=a[i].x;                    a[t].f=-a[i].f;                    a[i].f+=a[i].d;                    if(dfs(a[i].x))                        return 1;                    m--;                    a[i].f-=a[i].d;                    vv[a[i].x]=0;                }    }}

 

0 0