hdu 1839:Delay Constrained Maximum Capacity Path

来源:互联网 发布:海文考研网络课程 编辑:程序博客网 时间:2024/06/08 15:24

1点是珍贵矿场,N点是矿物加工厂,现在需要把矿物从1点运到N点,矿物在离开矿场T时间后就会变质,矿场与工厂之间有通道连接,每个通道有运输时间和最大运送量,求出从矿场到工厂运送时间不超过时间T的最大运送量。主意,一条道路上的最大运送量取决于它经过通路上的最小运送量。


二分+spfa过。知道每一段路的运送量,按从大到小进行排列,然后对这个排列进行二分,每次二分取中间的运送量作为限制,然后用时间作为距离进行spfa。spfa时用之前的那个限制作为最小运送量,松弛时只松弛那些运送量大于这个限制的边,这样就可以保证这个限制就是当前通路的最大运送量。然后判断此时N点是否连通或者N点的时间是否大于给定的时间T。如此循环直到二分完毕。


代码:

#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <iostream>using namespace std;struct Edge{    int to;    int cap;    int time;    int next;};const int inf=0x3f3f3f3f;int n,m,T,limit;int first[10005];Edge edge[50005*2];int cap[50005];int dis[10005];bool had[10005];queue <int> q;void spfa(){    memset(dis,0x3f,sizeof(dis));    memset(had,0,sizeof(had));    dis[1]=0;    q.push(1);    while(!q.empty()){        int t=q.front(); q.pop();        had[t]=0;        for(int i=first[t];i!=-1;i=edge[i].next){            if(dis[edge[i].to]>dis[t]+edge[i].time && edge[i].cap>=limit){                dis[edge[i].to]=dis[t]+edge[i].time;                if(!had[edge[i].to]){                    had[edge[i].to]=1;                    q.push(edge[i].to);                }            }        }    }}int main(){    //freopen("in.txt","r",stdin);    int Case; cin>>Case;    while(Case--){        cin>>n>>m>>T;        memset(first,-1,sizeof(first));        int e=0;        for(int i=0;i<m;i++){            int a,b,c,d;            cin>>a>>b>>c>>d;            edge[e].to=b;            edge[e].cap=c;            edge[e].time=d;            edge[e].next=first[a];            first[a]=e++;            edge[e].to=a;            edge[e].cap=c;            edge[e].time=d;            edge[e].next=first[b];            first[b]=e++;            cap[i]=c;        }        sort(cap,cap+m,greater<int>());        int mid,l=0,r=m-1;        while(l<=r){            mid=(l+r)/2;            limit=cap[mid];            spfa();            if(dis[n]==inf || dis[n]>T)                l=mid+1;            else                r=mid-1;        }        cout<<cap[l]<<endl;    }    return 0;}



然后就是不知道为什么,sort开始到二分结束那段改成下面这段代码就出问题了。先留着,以后再看。

        sort(cap,cap+m);        int mid,l=0,r=m-1;        while(l<=r){            mid=(l+r)/2;            limit=cap[mid];            spfa();            if(dis[n]==inf || dis[n]>T)                r=mid-1;            else                l=mid+1;        }        cout<<limit<<endl;


0 0