代码改变世界

hdu 1839 Delay Constrained Maximum Capacity Path

2013-05-17 09:42  bootstar  阅读(204)  评论(0编辑  收藏  举报
Delay Constrained Maximum Capacity Path

带限制的最短路。二分最小最大容量c,然后用dijkstra(优先队列优化)做最短路,在做最短路的时候,保证边的容量cap(i, j)>=c。时间复杂度为O(nlogn * log(max(c)))。当然在做最短路的时候是可以优化的,有以下几种优化办法:

1.时间优化,如果当前队列中弹出的点的时间(因为算的是从起点到该点的最短时间)超过时间限制,就不用搜了。

2.如果当前已经计算到了目标点(N),那么就可以不用再继续向下搜了。

最后需要注意的就是数据范围,由于多次因为对于比较大的数据处理失误,所以表示对于2*10^9,还是处理成long long最为妥当。

 

#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;

const int Vertex = 10500;
const int Edge = 50500;
const int INF = 0x3f3f3f3f;
typedef long long LL;

struct Pair{
    int v, t;
    Pair(int iv, int it):
        v(iv), t(it){}
    bool operator<(const Pair&a)const{
        return t > a.t;
    }
};

int d[Vertex], f[Vertex], e[Edge*2], to[Edge*2], tim[Edge*2];
LL cap[Edge*2];

bool vis[Vertex];
int N, M, T, tot;

void add(int v, int u, LL c, int t){
    e[tot] = f[v];
    to[tot] = u, cap[tot] = c, tim[tot] = t;
    f[v] = tot ++;
}

inline LL max(LL x, LL y){
    return x > y ? x : y;
}

bool bfs(int src, LL lim){
    //printf(">> %I64d\n", lim);
    memset(vis, 0, sizeof(vis));
    memset(d, 0x3f, sizeof(d));
    d[src] = 0;
    priority_queue<Pair> Q;
    Q.push(Pair(src, 0));
    while(!Q.empty()){
        Pair cur = Q.top();
        Q.pop();
        //printf(">>v = %d\n", cur.v);
        if(cur.t > T) break;
        if(vis[N]) break;
        if(vis[cur.v]) continue;
        vis[cur.v] = 1;

        for(int i = f[cur.v]; i!=-1; i = e[i]){
            int u = to[i];
            if(cap[i] < lim) continue;
            if(!vis[u] && d[u] > cur.t + tim[i]){
                d[u] = cur.t + tim[i];
                Q.push(Pair(u, d[u]));
            }
        }
    }
    return vis[N] && d[N] <= T;
}

int main(){
    int tcase;
    LL  l, r;
    freopen("test.in", "r", stdin);
    scanf("%d", &tcase);
    while(tcase--){
        scanf("%d%d%d", &N, &M, &T);

        tot = 0;
        memset(f, -1, sizeof(f));
        l = r = 0;

        for(int i = 0; i < M; i ++){
            int x, y, t; LL c;
            scanf("%d%d%I64d%d", &x, &y, &c, &t);
            add(x, y, c, t);
            add(y, x, c, t);
            r = max(r, c);
        }

        while(l <= r){
            LL mid = (l+r)/2;
            if(bfs(1, mid)) l = mid + 1;
            else r = mid - 1;
        }
        printf("%I64d\n", r);
    }
    return 0;
}