Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 17680 | Accepted: 8015 |
Description
Input
Output
Sample Input
3 3 3 1 10 2 1 2 2 2 1 3 3 1 2 6
Sample Output
7
題意:略;
以顾客为点,加一个源点和汇点,源点到顾客的权为他能去的猪槽的猪数量总和,顾客到汇点的权为顾客可以买的朱数量。顾客间如果有相同的猪槽加一条INF的边。
#include <iostream> #include <stdio.h> #include <queue> #include <cmath> #include <string.h> #include <vector> #include <algorithm> #include <map> #include <queue> using namespace std; #define LL long long #define scan(a) scanf("%d",&a) #define maxn 1111 #define REP(i,a,b) for(int i=a;i<b;++i) #define mset(a,b) memset(a,b,sizeof a) const LL mod = 1000000000; const int MAXN = 111;//点数的最大值 const int MAXM = 11100;//边数的最大值 const int INF = 0x3f3f3f3f; int pigs[1111]; vector<int> pigRoom[1111]; struct Edge { int to,next,cap,flow; }edge[MAXM];//注意是MAXM int tol; int head[MAXN]; int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN]; void init() { tol = 0; memset(head,-1,sizeof(head)); } //加边,单向图三个参数,双向图四个参数 void addedge(int u,int v,int w,int rw=0) { edge[tol].to =v;edge[tol].cap = w;edge[tol].next = head[u]; edge[tol].flow= 0;head[u] = tol++; edge[tol].to =u;edge[tol].cap = rw;edge[tol].next = head[v]; edge[tol].flow= 0;head[v]=tol++; } //输入参数:起点、终点、点的总数 //点的编号没有影响,只要输入点的总数 int sap(int start,int end,int N) { memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u = start; pre[u] = -1; gap[0] = N; int ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; for(int i = pre[u];i != -1; i = pre[edge[i^1].to]) if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; for(int i = pre[u];i != -1; i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for(int i = cur[u]; i != -1;i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if(flag) { u = v; continue; } int Min = N; for(int i = head[u]; i != -1;i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min+1; gap[dep[u]]++; if(u != start) u = edge[pre[u]^1].to; } return ans; } int main() { int s=0; int n,m; while(cin>>m>>n) { //mset(minf,0); int e=n+1; init(); REP(i,1,m+1) scan(pigs[i]); REP(i,1,n+1) { int A,sump=0,B; scan(A); REP(j,0,A) { int room; scan(room); if(pigRoom[room].size()==0) sump+=pigs[room]; pigRoom[room].push_back(i); } scan(B); addedge(s,i,sump); addedge(i,e,B); } REP(i,1,m+1) { int sz=pigRoom[i].size(); for(int j=0;j<sz-1;++j) { for(int k=j+1;k<sz;++k) { addedge(pigRoom[i][j],pigRoom[i][k],INF); } } } printf("%d\n",sap(s,e,n+2)); } }