【BZOJ2153】[SDOI2009]晨跑(最小费用最大流)

来源:互联网 发布:yii 框架商城源码下载 编辑:程序博客网 时间:2024/06/09 23:46

题目:

我是超链接

题解:

最小费用最大流裸题,拆点xi,yi,建立源点汇点,向1和n连边容量INF

代码:

#include <cstdio>#include <cstring> #include <iostream>#include <queue>#define INF 1e9#define N 40000using namespace std;int nxt[N*2+5],point[N*2+5],v[N*2+5],remind[N*2+5],cost[N*2+5],tot=-1,last[N*2+5];int maxflow,mincost,dis[N*2+5],n,m;bool vis[N*2+5];void addline(int x,int y,int cap,int value){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; remind[tot]=cap; cost[tot]=value;++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x; remind[tot]=0; cost[tot]=-value;}int addflow(int s,int t){int now=t,ans=INF;while (now!=s){ans=min(ans,remind[last[now]]);now=v[last[now]^1];}now=t;while (now!=s){remind[last[now]]-=ans;remind[last[now]^1]+=ans;now=v[last[now]^1];}return ans;}bool bfs(int s,int t){queue<int>q;q.push(s);memset(dis,0x7f,sizeof(dis));memset(vis,0,sizeof(vis));dis[s]=0;vis[s]=true;while (!q.empty()){int now=q.front(); q.pop();vis[now]=false;for (int i=point[now];i!=-1;i=nxt[i])  if (dis[v[i]]>dis[now]+cost[i] && remind[i])  {   dis[v[i]]=dis[now]+cost[i]; last[v[i]]=i; if (!vis[v[i]]) { vis[v[i]]=true; q.push(v[i]); }   }}if (dis[t]>INF) return false;int flow=addflow(s,t);maxflow+=flow;mincost+=flow*dis[t];return true;}void majoy(int s,int t){while(bfs(s,t));}int main(){memset(point,-1,sizeof(point));memset(nxt,-1,sizeof(nxt));int i,a,b,c;scanf("%d%d",&n,&m); for (i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); addline(a,b+n,1,c); }addline(0,1,INF,0);addline(n*2,n*2+1,INF,0);for (i=1;i<=n;i++)  addline(i+n,i,1,0);majoy(0,n*2+1);printf("%d %d",maxflow,mincost);}


1 0
原创粉丝点击