codevs1823 工作安排

来源:互联网 发布:apache ant 1.9.6安装 编辑:程序博客网 时间:2024/05/01 20:28
源向每个工作连流量c[i]的边,费用0
每个人向汇点连s[i]+1条边
流量t[i][j]-t[i][j-1],费用w[i][j]
工作和人根据A矩阵互相连边
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<string>#include<vector>#include<map>#include<set>#include<queue>#define R0(i,n) for(int i=0;i<n;++i)#define R1(i,n) for(int i=1;i<=n;++i)#define cl(x,c) memset(x,c,sizeof x)#define maxn 1000010#define INF 707406378using namespace std;typedef long long ll;int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}struct Edge {int from, to, cap, flow, cost;};int S, T;ll ans=0;vector<int> G[maxn];vector<Edge> edges;void add(int from, int to, int cap, int cost) {edges.push_back((Edge){from, to, cap, 0, cost});edges.push_back((Edge){to, from, 0, 0, -cost});int m = edges.size();G[from].push_back(m-2);G[to].push_back(m-1);}int d[maxn], p[maxn], A[maxn];bool inq[maxn];int cnt=1;int c[251],a[251][251],s[251],t[251][11],w[251][11];bool bf() {cl(inq,0);for(int i = S; i <= T; i++) d[i] = INF;d[S] = 0; inq[S] = 1; p[S] = 0; A[S] = INF;queue<int> Q;Q.push(S);while(!Q.empty()) {int x = Q.front(); Q.pop();inq[x] = 0;R0(i,G[x].size()){Edge& e = edges[G[x][i]];if(e.cap > e.flow && d[e.to] > d[x] + e.cost) {d[e.to] = d[x] + e.cost;A[e.to] = min(A[x], e.cap-e.flow);p[e.to] = G[x][i];if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; }}}}if(d[T] == INF) return 0;ans += d[T]*A[T];int x = T;while(x != S) {edges[p[x]].flow += A[T];edges[p[x]^1].flow -= A[T];x = edges[p[x]].from;}return 1;}int main() {S=1,T=1001;int m=read(),n=read();R1(i,n)c[i]=read();R1(i,m)R1(j,n)a[i][j]=read();R1(i,m){s[i]=read();R1(j,s[i])t[i][j]=read();t[i][s[i]+1]=INF;R1(j,s[i]+1)w[i][j]=read();}R1(i,n)add(0,i,c[i],0);R1(i,m)R1(j,n)if(a[i][j])add(j,n+i,INF,0);R1(i,m)R1(j,s[i]+1)add(n+i,T,t[i][j]-t[i][j-1],w[i][j]);while(bf());printf("%lld",ans);return 0;}


0 0