HDU 1839 Delay Constrained Maximum Capacity Path(二分+最短路)
链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1839
题目:
22 1 101 2 13 104 4 201 2 1000 152 4 999 61 3 100 153 4 99 4
1399
分析与总结:
因为每条路径的容量取决于这条路径中所有边中的最小容量,所以我们可以以此枚举最小容量。但是如果一个一个容量的枚举,那明显效率太低了。
通过分析,可以看出,如果最低容量越大,那么符合要求的路径就越少,所以,根据容量的大小,路径数量是单调的。
有了单调性,就可以利用二分法了。
只要把容量从大到小进行排序,然后二分之,很快便能算出答案。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int INF = 0x7fffffff;const int VN = 10005;const int EN = 50005;struct Edge{int v,next,cap,time;}E[EN*2];int n, m, t;int size;int head[VN];int cap[EN];int d[VN];int Time[VN];int limit;bool inq[VN];void init(){ size=0; memset(head, -1, sizeof(head));}void addEdge(int u,int v,int c,int d){ E[size].v=v; E[size].cap=c; E[size].time=d; E[size].next = head[u]; head[u] = size++;}int Dijkstra(int src){ memset(inq, 0, sizeof(inq)); for(int i=1; i<=n; ++i)d[i]=INF; d[src] = 0; queue<int>q; q.push(src); while(!q.empty()){ int u = q.front(); q.pop(); inq[u] = false; for(int e=head[u]; e!=-1; e=E[e].next)if(E[e].cap>=limit){ int tmp = d[u]+E[e].time; if(d[E[e].v] > tmp){ d[E[e].v] = tmp; if(!inq[E[e].v]){ inq[E[e].v] = true; q.push(E[e].v); } } } } return d[n];}int main(){ int T, u, v, c, d; scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&t); init(); for(int i=0; i<m; ++i){ scanf("%d%d%d%d",&u,&v,&c,&d); cap[i]=c; addEdge(u,v,c,d); addEdge(v,u,c,d); } sort(cap, cap+m,greater<int>()); // 二分求解 int left=0, right=m-1, mid; while(left<right){ mid = (left+right)>>1; limit = cap[mid]; int tmp=Dijkstra(1); if(tmp==INF || tmp>t){ left = mid+1; } else{ right=mid; } } printf("%d\n", cap[left]); } return 0;}—— 生命的意义,在于赋予它意义。
原创 http://blog.csdn.net/shuangde800 , By D_Double (转载请标明)