The topic: Given the number of students and the number of study groups, students to participate in the group need to pay fees, each group will spend c[i]*cnt[i]^2. Each student can participate in a K-group, asking the most students to attend the minimum expenses incurred.
Thought: If not count the next what ghost condition, see the picture is very obvious.
S-> each student f:k,c:0
Each student, each study group F:1,c:-f[i]
Each Study group->t f:1,c:1 * c[i],3 * c[i],5 * c[i],7 * C[i],......
The latter condition actually means that every student's K-chance doesn't have to be exhausted, but everyone has to attend at least one group. So we can each->t f:k-1,c:0
Then run the cost stream
CODE:
#define _crt_secure_no_deprecate#include <queue> #include <cstdio> #include <cstring> #include < iostream> #include <algorithm> #define MAX 510#define maxe 200010#define INF 0x3f3f3f3f#define S 0#define T (Max- 1) using namespace Std; struct Mincostmaxflow{int head[max],total;int next[maxe],aim[maxe],flow[maxe],cost[maxe];int from[MAX],p[MAX];int F [Max];bool V[max]; Mincostmaxflow () {total = 1;} void Add (int x,int y,int f,int c) {next[++total] = head[x];aim[total] = Y;flow[total] = F;cost[total] = c;head[x] = total; }void Insert (int x,int y,int f,int c) {Add (x,y,f,c); ADD (y,x,0,-c);} BOOL Spfa () {static queue<int> Q;while (!q.empty ()) Q.pop () memset (f,0x3f,sizeof (f)); Memset (V,false,sizeof (v)) ; F[s] = 0;q.push (S), while (!q.empty ()) {int x = Q.front (), Q.pop (); v[x] = false;for (int i = head[x]; i; i = Next[i]) if (flow [i] && f[aim[i]] > F[x] + cost[i]) {F[aim[i]] = f[x] + cost[i];if (!v[aim[i]]) v[aim[i]] = True,q.push (Aim[i]); FR Om[aim[i]] = x;p[aim[i]] = i;}} REturn f[t]! = INF; int Edmondskarp () {int re = 0;while (SPFA ()) {int max_flow = inf;for (int i = T; i = S; i = from[i]) max_flow = min (max_flow , Flow[p[i]]); for (int i = T; i = S; i = From[i]) {Flow[p[i]] = max_flow;flow[p[i]^1] + = Max_flow;} Re + = f[t] * max_flow;} return re;}} Solver;int points,groups,k;int c[max],f[max];bool map[max][max];int Main () {CIN >> points >> groups >> k;for (int i = 1; I <= groups; ++i) scanf ("%d", &c[i]), for (int i = 1; I <= groups; ++i) scanf ("%d", &f[i]); t i = 1; I <= points; ++i) for (int j = 1;j <= groups; ++j) scanf ("%1d", &map[i][j]); for (int i = 1; I <= points; ++i) {solver. Insert (s,i,k,0), for (int j = 1; j <= groups; ++j) if (Map[i][j]) solver. Insert (i,points + j,1,-f[j]);} if (k-1) for (int i = 1; I <= points; ++i) solver. Insert (i,t,k-1,0), for (int i = 1, i <= groups; ++i) for (int j = 1; j <= points; ++j) solver. Insert (i + points,t,1, ((J << 1)-1) * c[i]); cout << solver. Edmondskarp () << Endl; return 0;}
Bzoj 3442 Study Group fee flow