首页 > 代码库 > BZOJ 1221 软件开发

BZOJ 1221 软件开发

厉害了我的哥。。这建图。。

感谢http://www.cnblogs.com/rausen/p/4176729.html

这个建图的重点在于把需求和剩下的毛巾分开。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define maxv 2050#define maxn 1050#define maxe 1000050#define inf 2000000000using namespace std;int n,a,b,f,fa,fb,N[maxn],dis[maxv],nume=1,g[maxv],pree[maxv],prev[maxv],s,t;bool vis[maxv];queue <int> q;struct edge{    int v,f,c,nxt;}e[maxe];void addedge(int u,int v,int f,int c){    e[++nume].v=v;e[nume].f=f;e[nume].c=c;e[nume].nxt=g[u];g[u]=nume;    e[++nume].v=u;e[nume].f=0;e[nume].c=-c;e[nume].nxt=g[v];g[v]=nume;}void build(){    s=0;t=2*n+1;    for (int i=1;i<=n;i++)    {        addedge(s,i,N[i],0);addedge(i+n,t,N[i],0);        addedge(s,i+n,inf,f);        if (i+a+1<=n) addedge(i,i+a+n+1,inf,fa);        if (i+b+1<=n) addedge(i,i+b+n+1,inf,fb);    }    for (int i=1;i<=n-1;i++) addedge(i+n,i+n+1,inf,0);}bool spfa(){    for (int i=s;i<=t;i++) {pree[i]=prev[i]=-1;dis[i]=inf;vis[i]=false;}    q.push(s);vis[s]=true;dis[s]=0;    while (!q.empty())    {        int head=q.front();q.pop();        for (int i=g[head];i;i=e[i].nxt)        {            int v=e[i].v;            if ((e[i].f) && (dis[v]>dis[head]+e[i].c))            {                dis[v]=dis[head]+e[i].c;                pree[v]=i;prev[v]=head;                if (!vis[v]) {q.push(v);vis[v]=true;}            }        }        vis[head]=false;    }    if (dis[t]==inf) return false;    return true;}int dinic(){    int u=t,low=inf;    while (u!=s)    {        low=min(low,e[pree[u]].f);        u=prev[u];    }    u=t;    while (u!=s)    {        e[pree[u]].f-=low;e[pree[u]^1].f+=low;        u=prev[u];    }    return dis[t]*low;}int main(){    scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb);    for (int i=1;i<=n;i++) scanf("%d",&N[i]);    build();    int min_cost=0;    while (spfa()) min_cost+=dinic();    printf("%d\n",min_cost);    return 0;}

 

BZOJ 1221 软件开发