Network flow/Charge flow
Orz ZYF
Bare cost flow, according to the topic description can be built as follows:
S->i fee indicates that every student who joins the group I will need to spend the money, because it is related to the flow rate (number of people) two times, so to remove the edge ... Then everyone's entry fee is deducted directly from the expense (that is, the cost of each side minus a constant)
I->j+m based on matrix edge ... If the J student is able to apply for the first group I will be connected to an edge at a cost of 0.
The j+m->t capacity is k, and the cost is 0, which means that everyone is reported to K groups.
But this problem is very pit Ah! The limit is to participate in as many students as possible, that is to say, at the time of a certain loss, each person will only report a group ... Just build, the minimum cost maximum flow does not work!
We think that if a person signed up will reduce the total expenditure, then he must register a certain group, if not less ... Let the change amount to 0.
So we for Everyone J, Lian Bian S->j+m (k-1,0) said that this person can have a maximum of k-1 registration opportunity to give up directly! (because you want to make the number of participants as much as possible ...) So it can't be k)
1 /**************************************************************2 problem:34423 User:tunix4 language:c++5 result:accepted6 time:1560 Ms7 memory:3624 KB8 ****************************************************************/9 Ten //Bzoj 3442 One#include <vector> A#include <cstdio> -#include <cstring> -#include <cstdlib> the#include <iostream> -#include <algorithm> - #defineRep (i,n) for (int i=0;i<n;++i) - #defineF (i,j,n) for (int i=j;i<=n;++i) + #defineD (i,j,n) for (int i=j;i>=n;--i) - #definePB Push_back + using namespacestd; AInlineintGetint () { at intv=0, sign=1;CharCh=GetChar (); - while(ch<'0'|| Ch>'9'){if(ch=='-') sign=-1; Ch=GetChar ();} - while(ch>='0'&&ch<='9') {v=v*Ten+ch-'0'; Ch=GetChar ();} - returnv*Sign ; - } - Const intn=410, m=100000, inf=~0u>>2; intypedefLong LongLL; - /******************tamplate*********************/ to intN,m,k,ans,tmp,num,c[n]; + structedge{int from, To,v,c;}; - structnet{ the Edge E[m]; * inthead[n],next[m],cnt; $ voidInsintXintYintZintc) {Panax Notoginsenge[++cnt]=(Edge) {x,y,z,c}; -NEXT[CNT]=HEAD[X]; head[x]=CNT; the } + voidAddintXintYintZintc) { AIns (x,y,z,c); Ins (y,x,0,-c); the } + int from[n],q[m],d[n],s,t,ed; - BOOLinq[n],sign; $ BOOLSPFA () { $ intL=0, r=-1; -F (I,1, T) d[i]=INF; -d[s]=0; Q[++r]=s; inq[s]=1; the while(l<=S) { - intx=q[l++];Wuyiinq[x]=0; the for(intI=head[x];i;i=Next[i]) - if(e[i].v>0&& d[x]+e[i].c<D[e[i].to]) { Wud[e[i].to]=d[x]+e[i].c; - from[e[i].to]=i; About if(!Inq[e[i].to]) { $q[++r]=e[i].to; -inq[e[i].to]=1; - } - } A } + returnd[t]!=INF; the } - voidmcf () { $ intx=INF; the for(intI= from[t];i;i= from[E[i]. from]) thex=min (x,e[i].v); the for(intI= from[t];i;i= from[E[i]. from]){ thee[i].v-=x; -e[i^1].v+=x; in } theans+=x*D[t]; the } About voidinit () { theN=getint (); M=getint (); K=getint (); Cnt=1; thes=0; t=n+m+1; num=sign=0; tmp=-INF; theF (I,1, m) c[i]=getint (); + intx; -F (I,1, M) { thex=getint ();BayiF (J,1, n) Add (S,i,1, c[i]* (j*2-1)-x); the } the Chars[ -]; -F (I,1, N) { -scanf"%s", s+1); theF (J,1, M) { thex=s[j]-'0'; the if(x) Add (J,i+m,1,0); the } - } theF (I,1, n) Add (s,i+m,k-1,0), add (I+m,t,k,0); the while(SPFA ()) MCF (); theprintf"%d\n", ans);94 } the }g1; the the intMain () {98 #ifndef Online_judge AboutFreopen ("3442.in","R", stdin); -Freopen ("3442.out","W", stdout);101 #endif102 g1.init ();103 return 0;104}
View Code
"Bzoj" "3442" study Group