1. 程式人生 > 實用技巧 >藍橋杯 演算法訓練 Remember the A La Mode

藍橋杯 演算法訓練 Remember the A La Mode

費用流裸題

要注意的是浮點數判斷

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100005;
int cur[N],head[N],vis[N];
double dis[N];
const double inf=0x7fffffff;
const double eps=1e-6;
struct ss
{
    int u,v;
    int w;
    double val;
}e[N];
int n,m,s,t,cnt=1;
int aa[555];
int bb[555
]; double cc[55][55]; double ret=0; inline void add(int u,int v,int w,double val) { cnt++; e[cnt].v=v; e[cnt].w=w; e[cnt].val=val; e[cnt].u=head[u]; head[u]=cnt; } inline void addedge(int u,int v,int w,double val) { add(u,v,w,val); add(v,u,0,-val); } inline int spfa() {
for(int i=s;i<=t;++i)dis[i]=inf; vis[s]=1; dis[s]=0; queue<int>q; while(!q.empty())q.pop(); q.push(s); while(q.size()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=e[i].u) { int v=e[i].v;
int w=e[i].w; //if(w&&dis[v]>dis[u]+e[i].val) if(w&&((dis[v]-(dis[u]+e[i].val))>eps)) { dis[v]=dis[u]+e[i].val; if(!vis[v]) { vis[v]=1; q.push(v); } } } } return fabs(inf-dis[t])<eps?0:1;//dis[t]!=inf; } inline int dfs(int u,int flow) { if(u==t)return flow; int rest=flow; vis[u]=1; for(int i=cur[u];i&&rest;i=e[i].u) { cur[u]=i; int v=e[i].v; int w=e[i].w; if(w&&!vis[v]&&(fabs(dis[v]-(dis[u]+e[i].val))<eps)) { int k=dfs(v,min(w,rest)); if(k) { ret+=k*e[i].val; e[i].w-=k; e[i^1].w+=k; rest-=k; } } } vis[u]=0; return flow-rest; } int main() { scanf("%d%d",&n,&m); s=0;t=n+m+1; for(int i=1;i<=n;++i) { scanf("%d",&aa[i]); addedge(s,i,aa[i],0); } for(int i=1;i<=m;++i) { scanf("%d",&bb[i]); addedge(i+n,t,bb[i],0); } for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { scanf("%lf",&cc[i][j]); if(fabs(cc[i][j]+1)<eps)continue; addedge(i,j+n,aa[i],cc[i][j]); } } while(spfa()) { for(int i=s;i<=t;++i)cur[i]=head[i]; dfs(s,inf); } printf("%.2f to ",ret); cnt=1; ret=0; for(int i=s;i<=t;++i)head[i]=0; for(int i=1;i<=n;++i)addedge(s,i,aa[i],0); for(int i=1;i<=m;++i)addedge(i+n,t,bb[i],0); for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) { if(fabs(cc[i][j]+1)<eps)continue; addedge(i,j+n,aa[i],-cc[i][j]); } } while(spfa()) { for(int i=s;i<=t;++i)cur[i]=head[i]; dfs(s,inf); } printf("%.2f\n",-ret); return 0; }
View Code