hdu 4322 Candy 【多校3】【费用流】

来源:互联网 发布:知乎回答最多的人 编辑:程序博客网 时间:2024/05/15 04:41

费用流飘过~

#include<iostream>#include<vector>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<cmath>#include<cassert>#include<cstring>#include<iomanip>using namespace std;#ifdef _WIN32#define i64 __int64#define out64 "%I64d\n"#define in64 "%I64d"#else#define i64 long long#define out64 "%lld\n"#define in64 "%lld"#endif/************ for topcoder by zz1215 *******************/#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)#define FFF(i,a)        for( int i = 0 ; i < (a) ; i ++)#define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)#define S64(a)          scanf(in64,&a)#define SS(a)           scanf("%d",&a)#define LL(a)           ((a)<<1)#define RR(a)           (((a)<<1)+1)#define pb              push_back#define CL(Q)           while(!Q.empty())Q.pop()#define MM(name,what)   memset(name,what,sizeof(name))#define read            freopen("in.txt","r",stdin)#define write           freopen("out.txt","w",stdout)const int inf = 0x3f3f3f3f;const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;const double oo = 10e9;const double eps = 10e-9;const double pi = acos(-1.0);const int maxn = 55;const int end = 50;const int add = 25;struct zz{int from;int to;int c;int cost;int id;}zx;vector<zz>g[maxn];int tot;int n,m,k;int b[maxn];int like[maxn][maxn];int way[maxn];bool inq[maxn];int back[maxn];int backid[maxn];int minflow;int maxflow;void link(int now,int to,int c,int bc,int cost){zx.from = now;zx.to = to;zx.c = c;zx.cost = cost;zx.id = g[to].size();g[zx.from].pb(zx);swap(zx.from,zx.to);zx.c = bc;zx.cost = -cost;zx.id = g[now].size()-1;g[zx.from].pb(zx);return ;}void build(){for(int i=0;i<maxn;i++){g[i].clear();}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(like[j][i]){link(i,j+add,1,0,0);}}}for(int i=1;i<=n;i++){link(0,i,1,0,0);}for(int i=1;i<=m;i++){link(i+add,end,b[i]/k,0,k);}for(int i=1;i<=m;i++){if(b[i]%k!=0){link(i+add,end,1,0,b[i]%k);}}return ;}int spfa(){queue<int>q;MM(inq,false);MM(backid,-1);MM(back,-1);for(int i=0;i<maxn;i++){way[i]=-inf;}inq[0]=true;q.push(0);way[0]=0;int now,to,cost,temp;while(!q.empty()){now = q.front();q.pop();for(int i=0;i<g[now].size();i++){to = g[now][i].to;cost = g[now][i].cost;if(g[now][i].c>0){temp = way[now]+cost;if(way[to] < temp){way[to] = temp;back[to] = now;backid[to]=i;if(!inq[to]){q.push(to);inq[to]=true;}}}}inq[now]=false;}if(way[end]==-inf){return 0;}minflow = 1;temp = end;int id;temp = end;int ans = 0;int idx;while(back[temp]!=-1){now = back[temp];id = backid[temp];idx = g[now][id].id;ans += minflow*g[now][id].cost;g[now][id].c -= minflow;g[temp][idx].c += minflow;temp = now;}return ans;}bool ek(){build();maxflow = 0;int ans=0;int temp;while(true){temp = spfa();if(!temp) break;maxflow++;ans+= temp;}if(ans + n - maxflow >= tot){return true;}else{return false;}}int main(){int T;cin>>T;for(int tt=1;tt<=T;tt++){tot = 0;cin>>n>>m>>k;for(int i=1;i<=m;i++){cin>>b[i];tot+=b[i];}for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){cin>>like[i][j];}}cout<<"Case #"<<tt<<": ";if(ek()){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}}return 0;}