BZOJ 3931 [CQOI2015]网络吞吐量 最短路+最大流
2017-03-13 08:59
417 查看
题目大意:每个点有流量限制vi,只有在从起点到终点的最短路径上的边才可以走,求最大流量。
将每个点分成入点与出点,入点与出点连一条vi的边(除起点与终点),最短路径上的边的流量为INF。
1.网络流建图时若边不从0开始存一定要注意异或找反边有可能是错误的
2.数组又开小了QAQ
将每个点分成入点与出点,入点与出点连一条vi的边(除起点与终点),最短路径上的边的流量为INF。
1.网络流建图时若边不从0开始存一定要注意异或找反边有可能是错误的
2.数组又开小了QAQ
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> #define INF (1ll<<60) #define N 2005 using namespace std; #define int long long struct Edge { int from,to,nxt,cap; }e[N*400]; int S,T,n,m,top=-1,v ,fir ,d ,cur ; bool k ; void Add_Edge(int from,int to,int cap) { e[++top].from=from; e[top].to=to; e[top].cap=cap; e[top].nxt=fir[from]; fir[from]=top; e[++top].from=to; e[top].to=from; e[top].cap=0; e[top].nxt=fir[to]; fir[to]=top; return ; } struct Node { int ord,val; Node(int _,int __):ord(_),val(__){} bool operator < (const Node& rhs) const {return val>rhs.val;} }; void Dijkstra() { priority_queue<Node> q; for(int i=1;i<=n;i++) d[i]=INF; d[1]=0; q.push(Node(1,0)); while(!q.empty()) { Node tmp=q.top(); q.pop(); int x=tmp.ord,val=tmp.val; if(k[x]) continue; k[x]=true; for(int i=fir[x];i;i=e[i].nxt) { if(d[e[i].to]<=val+e[i].cap) continue; //printf("***"); d[e[i].to]=val+e[i].cap; q.push(Node(e[i].to,d[e[i].to])); } } return ; } bool bfs() { memset(d,-1,sizeof d); static int q ; int l,r; l=r=0; q[r++]=S; d[S]=0; while(l<r){ int x=q[l++]; for(int i=fir[x];i;i=e[i].nxt) { if(e[i].cap<=0 || d[e[i].to]!=-1) continue; q[r++]=e[i].to; d[e[i].to]=d[x]+1; if(e[i].to==T) return true; } } return false; } int dfs(int x,int now) { if(!now || x==T) return now; int flow=0,f; for(int& i=cur[x];i;i=e[i].nxt) { if(d[e[i].to]!=d[x]+1) continue; f=dfs(e[i].to,min(now,e[i].cap)); if(f<1) continue; flow+=f; now-=f; e[i].cap-=f; e[i^1].cap+=f; if(!now) break; } return flow; } int Dinic() { int ans=0; while(bfs()){ for(int i=0;i<=T;i++) cur[i]=fir[i]; ans+=dfs(S,INF); } return ans; } #undef int int main() { #define int long long scanf("%lld%lld",&n,&m); for(int i=1;i<=m;i++) { int x,y,z; scanf("%lld%lld%lld",&x,&y,&z); e[i].from=x; e[i].to=y; e[i].cap=z; e[i].nxt=fir[x]; fir[x]=i; e[i+m].from=y; e[i+m].to=x; e[i+m].cap=z; e[i+m].nxt=fir[y]; fir[y]=i+m; } for(int i=1;i<=n;i++) scanf("%lld",&v[i]); Dijkstra(); memset(fir,0,sizeof fir); top=((m*2)&1 ? m*2 : m*2+1), S=1, T=2*n+2; for(int i=1;i<=m*2;i++) if(d[e[i].from]+e[i].cap==d[e[i].to]) Add_Edge(2*e[i].from+1,2*e[i].to,INF); for(int i=2;i<n;i++) Add_Edge(2*i,2*i+1,v[i]); Add_Edge(S,3,INF); Add_Edge(n*2,T,INF); printf("%lld\n",Dinic()); return 0; }
相关文章推荐
- BZOJ 3931: [CQOI2015]网络吞吐量( 最短路 + 最大流 )
- bzoj 3931 [CQOI2015]网络吞吐量(最短路,最大流)
- BZOJ 3931 CQOI 2015 网络吞吐量 最短路+最大流
- BZOJ 3931 CQOI 2015 网络吞吐量 最大流 最短路
- 网络流(最大流) CQOI 2015 BZOJ 3931 网络吞吐量
- BZOJ 3931: [CQOI2015]网络吞吐量【最短路+网络流
- bzoj 3931: [CQOI2015]网络吞吐量 -- 最短路+网络流
- 3931: [CQOI2015]网络吞吐量 最短路+最大流
- BZOJ 3931: [CQOI2015]网络吞吐量 dijstra+heap+最大流
- bzoj 3931: [CQOI2015]网络吞吐量(最短路+网络流)
- BZOJ 3931: [CQOI2015]网络吞吐量 最大流
- 【最短路】【最大流】bzoj3931 [CQOI2015]网络吞吐量
- BZOJ 3931 [CQOI2015]网络吞吐量 最短路+最大流
- BZOJ 3931: [CQOI2015]网络吞吐量
- 【BZOJ 3931】[CQOI2015]网络吞吐量 dijkstra+最大流
- ●BZOJ 3931 [CQOI2015]网络吞吐量
- 【BZOJ】【3931】【CQOI2015】网络吞吐量
- bzoj 3931: [CQOI2015]网络吞吐量
- BZOJ 3931 网络吞吐量 (最短路+最大流)
- BZOJ 3931 CQOI2015 网络吞吐量 Dijkstra+网络流