nefu500(二分+最大流)
2016-04-18 21:43
399 查看
这道题目是求所走的路线中,费用最大的那条边的值最小,一般说什么最大的最小之类的就应该是二分,其实这个题刚开始没有想到是网络流的,因为费用和流量都有,有点蒙,后来发现件数当流量,然后费用当条件,就ok了
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int oo=1e9; const int mm=222222; const int mn=10005; int node,src,dest,edge,n,m,x; int ver[mm],flow[mm],next[mm]; int head[mn],work[mn],dis[mn],q[mn],a[mn]; void prepare(int _node,int _src,int _dest) { node=_node,src=_src,dest=_dest; for(int i=0; i<node; i++) head[i]=-1; edge=0; } void addedge(int u,int v,int c) { ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++; ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++; } bool Dicnic_bfs() { int i,u,v,l,r=0; for(i=0; i<node; ++i) dis[i]=-1; dis[q[r++]=src]=0; for(l=0; l<r; ++l) for(i=head[u=q[l]]; i>=0; i=next[i]) { if(flow[i]&&dis[v=ver[i]]<0) { dis[q[r++]=v]=dis[u]+1; if(v==dest) return 1; } } return 0; } int Dicnic_dfs(int u,int exp) { if(u==dest) return exp; for(int &i=work[u],v,tmp; i>=0; i=next[i]) if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dicnic_dfs(v,min(exp,flow[i])))>0) { flow[i]-=tmp; flow[i^1]+=tmp; return tmp; } return 0; } int Dicnic_flow() { int i,ret=0,delta; while(Dicnic_bfs()) { for(i=0; i<node; i++) work[i]=head[i]; while(delta=Dicnic_dfs(src,oo)) ret+=delta; } return ret; } struct sa { int from,to,cost,cap; }s[mm]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(s,0,sizeof(s)); memset(a,0,sizeof(a)); int ans=0,maxn=0,sum=0,sumn=0; bool flag=0; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); sum+=a[i]; } for(int i=1; i<=m; i++) { scanf("%d%d%d%d",&s[i].from,&s[i].to,&s[i].cost,&s[i].cap); maxn=max(maxn,s[i].cost); } int left=0,right=maxn,mid=-1; while(left<=right) { mid=(left+right)/2; prepare(n+2,1,n+1); for(int i=1; i<=m; i++) { if(s[i].cost<=mid) { addedge(s[i].from,s[i].to,s[i].cap); } } for(int i=1;i<=n;i++) { if(a[i]!=0) addedge(i,n+1,a[i]); } sumn=Dicnic_flow(); if(sumn==sum) { flag=1; ans=mid; right=mid-1; } else { left=mid+1; } } if(flag==false) printf("-1\n"); else printf("%d\n",ans); } return 0; }
相关文章推荐
- 初学图论-Kahn拓扑排序算法(Kahn's Topological Sort Algorithm)
- 初学图论-Bellman-Ford单源最短路径算法
- 初学图论-DAG单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- 封装好的Folyd建图,C++源码
- LCA模板
- 图论学习笔记之一——Floyd算法
- 【LCA】SPOJ QTREE2
- poj 3249 Test for Job 最长路
- HDU 2544
- Timus 1557 Network Attack DFS+各种各种...
- HDU1289 Tarjan-模板题
- Poj2638 网络流+最短路+二分答案
- Aizu1311 分层图最短路 (...大概)
- BZOJ3275 Number (最小割)
- [笔记] 网络流-最大流 POJ-1273\HDU-4240
- HDU 3631 Shortest Path
- 上下界网络流初探
- Dijkstra算法