BZOJ 1877 [SDOI2009]晨跑 费用流
2017-06-05 20:30
411 查看
题目大意:给出一张n个点m条单向边的图,经过一条边可以获得一个边权c,每个点只能走一次(1、n除外),每条边也只能走一次。现多次从1出发到达n,问最大化经过点数最小化权值和。
很明显最小费用最大流跑一跑。
对于点的限制把每个点(1、n除外)拆成入点和出点,从入点到出点连一条流量为1费用为0的边
将点1的入点设为源,点n的出点设为汇,这两个点的入点与出点之间连一条流量为INF费用为0的边
对于每条边(u,v),从u的出点到v的入点连一条流量为1费用为c的边
很明显最小费用最大流跑一跑。
对于点的限制把每个点(1、n除外)拆成入点和出点,从入点到出点连一条流量为1费用为0的边
将点1的入点设为源,点n的出点设为汇,这两个点的入点与出点之间连一条流量为INF费用为0的边
对于每条边(u,v),从u的出点到v的入点连一条流量为1费用为c的边
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define N 405 #define M 50005 #define INF 2000000000 using namespace std; struct Edge { int from,to,nxt,cap,cost; Edge() {} Edge(int _from,int _to,int _nxt,int _cap,int _cost): from(_from),to(_to),nxt(_nxt),cap(_cap),cost(_cost) {} }e[M]; int n,m,tot=-1,S,T,tot_cost,tot_flow,fir ,d ; bool inq ,vis ; void Add_Edge(int from,int to,int cap,int cost) { e[++tot]=Edge(from,to,fir[from],cap,cost), fir[from]=tot; e[++tot]=Edge(to,from,fir[to],0,-cost), fir[to]=tot; return ; } bool SPFA() { for(int i=S;i<=T;++i) d[i]=INF; queue<int> q; d[S]=0; q.push(S), inq[S]=true; while(!q.empty()) { int x=q.front(); q.pop(); inq[x]=false; for(int i=fir[x];~i;i=e[i].nxt) { if(!e[i].cap || d[e[i].to]<=d[x]+e[i].cost) continue; d[e[i].to]=d[x]+e[i].cost; if(!inq[e[i].to]) q.push(e[i].to), inq[e[i].to]=true; } } if(d[T]!=INF) return true; return false; } int dfs(int x,int now) { if(x==T || !now) { tot_cost+=now*d[T]; return now; } int f,flow=0; vis[x]=true; for(int i=fir[x];~i;i=e[i].nxt) { if(vis[e[i].to] || d[e[i].to]!=d[x]+e[i].cost) continue; f=dfs(e[i].to,min(now,e[i].cap)); if(!f) continue; e[i].cap-=f, e[i^1].cap+=f; flow+=f, now-=f; if(!now) break; } if(!flow) d[x]=-1; return flow; } void Costflow() { tot_cost=tot_flow=0; while(SPFA()) { for(int i=S;i<=T;++i) vis[i]=false; tot_flow+=dfs(S,INF); } return ; } int main() { memset(fir,-1,sizeof fir); scanf("%d%d",&n,&m); S=1, T=2*n; for(int i=1;i<=m;++i) { int x,y,z; scanf("%d%d%d",&x,&y,&z); Add_Edge(x+n,y,1,z); } for(int i=2;i<n;++i) Add_Edge(i,i+n,1,0); Add_Edge(S,S+n,INF,0); Add_Edge(T/2,T,INF,0); Costflow(); printf("%d %d\n",tot_flow,tot_cost); return 0; }
相关文章推荐
- 【bzoj1877】[SDOI2009]晨跑 费用流
- BZOJ_1877_[SDOI2009]晨跑_费用流
- BZOJ1877 [SDOI2009]晨跑 【费用流】
- Bzoj1877 SDOI 2009 晨跑 费用流
- 【BZOJ 1877】 [SDOI2009]晨跑(费用流)
- bzoj1877: [SDOI2009]晨跑(费用流)
- [BZOJ 1877][SDOI2009]晨跑(费用流)
- Bzoj 1877: [SDOI2009]晨跑(费用流)
- [BZOJ1877][SDOI2009]晨跑(费用流)
- BZOJ 1877: [SDOI2009]晨跑(费用流)
- [SDOI2009][bzoj1877] 晨跑 [费用流]
- [bzoj1877][SDOI2009]晨跑 费用流
- bzoj 1877: [SDOI2009]晨跑 费用流
- BZOJ 1877: [SDOI2009]晨跑 费用流
- bzoj1877 [SDOI2009]晨跑(费用流)
- BZOJ 1877: [SDOI2009]晨跑 费用流拆点
- 【codevs 2306】【bzoj 1877】[SDOI 2009]晨跑(费用流)
- BZOJ 1877: [SDOI2009]晨跑 费用流
- 【bzoj1877】【SDOI2009】【晨跑】【费用流】
- bzoj1877 [SDOI2009]晨跑 费用流