hdu 1839(二分+最短路)

来源:互联网 发布:诺基亚lumia800软件 编辑:程序博客网 时间:2024/06/07 21:43

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1839

思路:先给容量从大到小排序,然后二分,每次都一次spfa一下,判断当前的cost[n]的值。。。

View Code
 1 #include<iostream> 2 #include<queue> 3 #include<vector> 4 typedef long long ll; 5 const int MAXN=10000+10; 6 const ll inf=1e60; 7 using namespace std; 8 struct Node{ 9     int v,w,t;10 };11 vector<Node>mp[MAXN];12 ll cost[MAXN];13 ll weight[MAXN*5];14 int n,m,time;15 int limit;16 17 18 int cmp(const ll a,const ll b){19     return a>b;20 }21 22 23 void SPFA(int u){24     for(int i=1;i<=n;i++)cost[i]=inf;25     cost[1]=0;26     queue<int>Q;27     Q.push(u);28     while(!Q.empty()){29         int u=Q.front();30         Q.pop();31         for(int i=0;i<mp[u].size();i++){32             int v=mp[u][i].v;33             int t=mp[u][i].t;34             int w=mp[u][i].w;35             //这儿实在是太妙了,每次选的边都有一个限制就行了36             if(cost[u]+t<cost[v]&&w>=limit){37                 cost[v]=cost[u]+t;38                 Q.push(v);39             }40         }41     }42 }43 44 int main(){45     int _case;46     scanf("%d",&_case);47     while(_case--){48         scanf("%d%d%d",&n,&m,&time);49         for(int i=1;i<=n;i++)mp[i].clear();50         memset(weight,0,sizeof(weight));51         for(int i=1;i<=m;i++){52             int u,v,w,t;53             scanf("%d%d%d%d",&u,&v,&w,&t);54             Node p1,p2;55             p1.v=u,p2.v=v;56             p1.t=p2.t=t;57             p1.w=p2.w=w;58             weight[i]=w;//用来记录每条路的容量;59             mp[u].push_back(p2);60             mp[v].push_back(p1);61         }62         sort(weight+1,weight+m+1,cmp);63         //二分64         int low=1,high=m;65         while(low<=high){66             int mid=(low+high)/2;67             limit=weight[mid];//每次都选择一个限制68             SPFA(1);69             if(cost[n]==inf||cost[n]>time){70                 low=mid+1;71             }else 72                 high=mid-1;73         }74         printf("%d\n",weight[low]);75     }76     return 0;77 }

 

0 0