zoj 3229 Shoot the Bullet

来源:互联网 发布:一千零一夜 淘宝观看 编辑:程序博客网 时间:2024/05/08 06:52

题意:

有个名叫Aya(她明明是个女孩子但是网上很多人爱把她译作diaosi。。)的人,要给m个可爱的女孩子拍照,规定在n天的时间内,第i个女孩子至少要被拍Gi张照片,第i天只能给某个集合的女孩子拍照,且每个女孩子的拍照数量还要符合一定限制(上下界)。求在满足上述要求下,n天最多能拍到多少照片?


solution:

先构造一个可行流,按照无源汇可行流的方法构图,最后在t向s连一条INF的边,这样就是一个循环流的图了,超级源汇先跑一次,得到的是可行流。然后删掉超级源汇,t到s的边,再跑一边st最大流,就能把自由流都统计进来了。也就是说,ans = 可行流 + 自由流

#include<iostream>#include<cstring>#include<vector>#include<queue>#include<algorithm>#include<cmath>#include<cstdio>#include<bitset>using namespace std;const int maxn = 4020;const int maxm = 1E6 + 5E5 + 20;const int INF = 0x3fff3fff;struct E{int to,cap,flow,Num; E(){}E(int to,int cap,int flow,int Num):to(to),cap(cap),flow(flow),Num(Num){}}edgs[maxm];int n,m,s,t,S,T,tot,cnt,tp,in[maxn],out[maxn],Ans[maxm],cur[maxn],L[maxn];vector <int> v[maxn];queue <int> Q;void Add(int x,int y,int cap,int Num){v[x].push_back(cnt); edgs[cnt++] = E(y,cap,0,Num);v[y].push_back(cnt); edgs[cnt++] = E(x,0,0,0);}bool BFS(int ss,int tt){for (int i = 1; i <= tot; i++) L[i] = 0;L[ss] = 1; Q.push(ss);while (!Q.empty()){int k = Q.front(); Q.pop();for (int i = 0; i < v[k].size(); i++){if (v[k][i] >= cnt) break;E e = edgs[v[k][i]];if (e.cap == e.flow || L[e.to]) continue;L[e.to] = L[k] + 1; Q.push(e.to);}}return L[tt];}int Dfs(int x,int a,int goal){if (x == goal) return a; int flow = 0;for (int &i = cur[x]; i < v[x].size(); i++){if (v[x][i] >= cnt) break;E &e = edgs[v[x][i]];if (e.cap == e.flow || L[e.to] != L[x] + 1) continue;int f = Dfs(e.to,min(a,e.cap - e.flow),goal);if (!f) continue; flow += f; e.flow += f;edgs[v[x][i]^1].flow -= f; a -= f;if (!a) return flow;}if (!flow) L[x] = -1; return flow;}int Dinic(int ss,int tt){int MaxFlow = 0;while (BFS(ss,tt)){for (int i = 1; i <= tot; i++) cur[i] = 0;MaxFlow += Dfs(ss,INF,tt);}return MaxFlow;}int getint(){char ch = getchar(); int ret = 0;while (ch < '0' || '9' < ch){if (ch == EOF) return -1;ch = getchar();}while ('0' <= ch && ch <= '9')ret = ret*10 + ch - '0',ch = getchar();return ret;}int main(){#ifdef DMCfreopen("DMC.txt","r",stdin);#endifwhile (scanf("%d%d",&n,&m) != EOF){tot = m; s = ++tot;t = ++tot; S = ++tot; T = ++tot;for (int i = 1; i <= m; i++) scanf("%d",&out[i]),in[t] += out[i],Add(i,t,INF,0);for (int i = 1; i <= n; i++){int k,D; scanf("%d%d",&k,&D); ++tot;while (k--){int x,l,r; scanf("%d%d%d",&x,&l,&r);Add(tot,++x,r - l,i); Ans[++tp] = l;in[x] += l; out[tot] += l; }Add(s,tot,D,0);}int Cur = cnt,sum = 0; Add(t,s,INF,0);for (int i = 1; i <= tot; i++){int du = in[i] - out[i];if (du > 0) Add(S,i,du,0),sum += du;else if (du < 0) Add(i,T,-du,0);}int MaxFlow = Dinic(S,T);if (MaxFlow < sum) puts("-1");else{cnt = Cur; MaxFlow += Dinic(s,t);printf("%d\n",MaxFlow); int now = 0;for (int i = 1; i <= tot; i++){for (int j = 0; j < v[i].size(); j++){E e = edgs[v[i][j]]; if (!e.Num) continue;printf("%d\n",Ans[++now] + e.flow);}}}for (int i = 1; i <= tp; i++) Ans[i] = 0;puts(""); cnt = tp = 0;for (int i = 1; i <= tot; i++) v[i].clear(),in[i] = out[i] = 0;}return 0;}


代码调了1h+在zoj都是JIE。。。(JIE是什么鬼?)

翻译告诉我说什么评测系统内部错误?

网上随意找了几份AC代码交上去也是JIE= =。。。。。。。

搞不懂了,,,,不管了。。。。过几天再交上去看看(不保证代码正确性)

0 0
原创粉丝点击