HDU6118 度度熊的交易计划 【费用流】
2017-08-14 14:30
190 查看
链接
百度之星的时候脑抽了…
跑了n次Dijkstra求了个全源最短路
拆点 i和j′的费用为cj−ai−disi,j
S到i,流量为bi,费用为0, i′到T流量为di,费用为0
这样边数2n2,TLE到爆
正解...直接按输入建图即可,拆点都不需要...
S到i的费用为ai,流量bi
i到T费用−ci,流量di
<i,j>有一条长为k的边,则建一条i到j,费用k,流量inf的边,跑一遍,费用取反即可
但是这样即使利润<0的交易也会被计算在内,所以spfa增广的dis>=0时结束掉即可
百度之星的时候脑抽了…
跑了n次Dijkstra求了个全源最短路
拆点 i和j′的费用为cj−ai−disi,j
S到i,流量为bi,费用为0, i′到T流量为di,费用为0
这样边数2n2,TLE到爆
正解...直接按输入建图即可,拆点都不需要...
S到i的费用为ai,流量bi
i到T费用−ci,流量di
<i,j>有一条长为k的边,则建一条i到j,费用k,流量inf的边,跑一遍,费用取反即可
但是这样即使利润<0的交易也会被计算在内,所以spfa增广的dis>=0时结束掉即可
#include<stdio.h> #include<bits/stdc++.h> #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define MEM(a,x) memset(a,x,sizeof(a)) #define lowbit(x) ((x)&-(x)) using namespace std; const int inf=1e9+7; const int MOD = 1e9+7; const int INF = inf; const int N = 500 + 50; const int M = 1000*4+4*N + 100;//边 struct MinFlow{ struct Edge{ int to,c,w,next;//c:流量,w:费用 }edge[M]; int head ; int nume=0; inline void addEdge(int k,int u,int v,int c,int w){ edge[k].to=v, edge[k].c=c, edge[k].w=w, edge[k].next=head[u]; head[u]=k; } inline void addEdge(int u,int v,int c,int w){ addEdge(nume++,u,v,c,w); addEdge(nume++,v,u,0,-w); } void init(int n){ fill(head,head+n+1,-1); nume=0; } bool used ; int dis ,load ,p ;//距离 ,前驱边,前驱点 bool spfa(int s,int e,int n){ deque<int>que; for(int i=0;i<=n;++i){ dis[i]=INF; load[i]=p[i]=-1; used[i]=false; } que.push_back(s); dis[s]=0; used[s]=true; while(!que.empty()){ int u=que.front(); que.pop_front(); used[u]=false; for(int i=head[u];i!=-1;i=edge[i].next){ if(edge[i].c>0){ int v=edge[i].to; if(dis[v]>dis[u]+edge[i].w){ dis[v]=dis[u]+edge[i].w; p[v]=u; load[v]=i; if(used[v]==false){ used[v]=true; que.push_back(v); } } } } } return dis[e]<0;//dis[e]>=0时,利润<=0,结束计算 } int min_cost_flow(int s,int t,int n){ int ansflow=0,anscost=0;//最大流,最小费用 while(spfa(s,t,n)){ int u=t; int f=INF; while(p[u]!=-1){ f=min(f,edge[load[u]].c); u=p[u]; } u=t; while(p[u]!=-1){ edge[load[u]].c-=f; edge[load[u]^1].c+=f; u=p[u]; } anscost+=dis[t]*f; ansflow+=f; } return anscost; } }minflow; int slove(int n,int m){ const int S=n+1,T=S+1; minflow.init(T+1); for(int i=1;i<=n;++i){ int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); minflow.addEdge(S,i,b,a); minflow.addEdge(i,T,d,-c); } for(int i=1;i<=m;++i){ int u,v,k; scanf("%d%d%d",&u,&v,&k); minflow.addEdge(u,v,inf,k); minflow.addEdge(v,u,inf,k); } return -minflow.min_cost_flow(S,T,T+1); } int main() { //freopen("/home/lu/code/r.txt","r",stdin); //freopen("/home/lu/code/w.txt","w",stdout); int n,m; while(~scanf("%d%d",&n,&m)){ printf("%d\n",slove(n,m)); } return 0; }
相关文章推荐
- HDU6118:度度熊的交易计划(入门级最小费用可行流)
- hdu 6118 度度熊的交易计划 费用流
- hdu 6118 度度熊的交易计划 (最小费用最大流
- hdu 6118 度度熊的交易计划 费用流
- hdu 6118 度度熊的交易计划 (最小费用最大流
- HDU 6118 度度熊的交易计划 (最小费用最大流模板题)
- [HDOJ6118] 度度熊的交易计划(最小费用可行流)
- [HDU6118][2017"百度之星"程序设计大赛 - 初赛(B)]度度熊的交易计划
- hdu 6118 度度熊的交易计划 (最小费用最大流
- [HDU6118][2017"百度之星"程序设计大赛 - 初赛(B)]度度熊的交易计划
- hdu 6118 度度熊的交易计划(最小费用可行流)
- hdu 6118 度度熊的交易计划 (最小费用最大流
- Hdu6118 度度熊的交易计划(2017"百度之星"程序设计大赛 - 初赛(B))
- hdu 6118 度度熊的交易计划 (最小费用最大流
- HDU 6118 度度熊的交易计划(最小费用可行流)
- HDU 6118 度度熊的交易计划(费用流)
- HDU6118-度度熊的交易计划(最小可行流)
- hdu 6118 度度熊的交易计划【费用流模板题】
- hdu 6118 度度熊的交易计划(可行费用流)
- HDU6118 度度熊的交易计划