赞
踩
舟亢学长
裸最小费用最大流(最短路)
裸最大费用最大流(负权最短路再取反)
本来比赛的时候有时间敲 预估自己30min
结果赛后补题敲了1h tm还WA了好几发
请学长debug结果是数组开小了GG
我怎么这么菜啊
还是对费用流理解不深啊
弧优化+SLF优化的SPFA是不可能被卡掉的啊
这样看来,手敲板子的学弟还真是遥不可及啊……
不禁让人怀念过目不忘的初中高中生涯……
如今已是按板子敲都能出各种bug的老年人了……
- #include<bits/stdc++.h>
- typedef long long ll;
- using namespace std;
- const int maxn=110;//点的数量
- const int maxm=50005;//2*maxn*maxn+2*maxn 源点出maxn条 汇点入maxn条 中间点两两连
- const ll INF=1e18;
- struct edge
- {
- int u,v;
- ll cos,nex,w;
- }e[maxm];
- ll vis[2*maxn],dis[2*maxn];
- ll l[2*maxn],r[2*maxn],cost[2*maxn][2*maxn];
- ll tot;//总费用
- int head[maxn],cnt;
- int n,m;
- int s,t;
- void add(int u,int v,ll w,ll cos)
- {
- e[cnt].v=v;
- e[cnt].w=w;
- e[cnt].cos=cos;
- e[cnt].nex=head[u];
- head[u]=cnt++;
- }
- void add2(int u,int v,ll w,ll cos)
- {
- add(u,v,w,cos);
- add(v,u,0,-cos);
- }
- bool spfa()
- {
- for(int i=0;i<2*maxn;++i)
- dis[i]=INF;
- memset(vis,0,sizeof vis);
- vis[t]=1;
- dis[t]=0;
- deque<int>q;
- q.push_back(t);
- while(!q.empty())
- {
- int u=q.front();
- vis[u]=0;
- q.pop_front();
- for(int i=head[u];~i;i=e[i].nex)
- {
- int v=e[i].v;
- if(e[i^1].w>0&&dis[v]>dis[u]-e[i].cos)
- {
- dis[v]=dis[u]-e[i].cos;
- if(!vis[v])
- {
- vis[v]=1;
- if(!q.empty()&&dis[v]<dis[q.front()])
- q.push_front(v);
- else q.push_back(v);
- }
- }
- }
- }
- return dis[s]<INF;
- }
- ll dfs(int u,ll low,ll &tot)
- {
- vis[u]=1;
- if(u==t)return low;
- ll ans=0;
- for(int i=head[u];~i;i=e[i].nex)
- {
- int v=e[i].v;
- if(!vis[v]&&e[i].w&&dis[v]==dis[u]-e[i].cos)
- {
- ll now=dfs(v,min(low,e[i].w),tot);
- if(now>0)
- {
- tot+=e[i].cos*now;
- low-=now;
- ans+=now;
- e[i].w-=now;
- e[i^1].w+=now;
- if(low==0)break;
- }
- }
- }
- return ans;
- }
- ll max_flow(int s,int t,ll &tot)//tot返回费用 函数返回值为最大流
- {
- ll ans=0;
- while(spfa())
- {
- vis[t]=1;
- while(vis[t])
- {
- memset(vis,0,sizeof vis);
- ans+=dfs(s,INF,tot);
- }
- }
- return ans;
- }
- void init()
- {
- cnt=0;tot=0;
- for(int i=0;i<2*maxn;++i)
- dis[i]=INF;
- memset(head,-1,sizeof head);
- memset(vis,0,sizeof vis);
- }
- int main()
- {
- init();
- scanf("%d%d",&m,&n);
- //超级源 超级汇
- s=0;t=m+n+1;
- //左供货 右需求
- for(int i=1;i<=m;++i)
- {
- scanf("%lld",&l[i]);
- add2(s,i,l[i],0);//超级源点
- }
- for(int i=1;i<=n;++i)
- {
- scanf("%lld",&r[i]);
- add2(m+i,t,r[i],0);//超级汇点
- }
- for(int i=1;i<=m;++i)
- {
- for(int j=1;j<=n;++j)
- {
- scanf("%lld",&cost[i][j]);
- add2(i,m+j,l[i],cost[i][j]);//l[i]的流量 dis的费用
- }
- }
- max_flow(s,t,tot);
- printf("%lld\n",tot);
- init();
- for(int i=1;i<=m;++i)
- {
- add2(s,i,l[i],0);//超级源点
- }
- for(int i=1;i<=n;++i)
- {
- add2(m+i,t,r[i],0);//超级汇点
- }
- for(int i=1;i<=m;++i)
- {
- for(int j=1;j<=n;++j)
- {
- add2(i,m+j,l[i],-cost[i][j]);//l[i]的流量 dis的费用
- }
- }
- max_flow(s,t,tot);
- printf("%lld\n",-tot);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。