[关闭]
@shixinyi 2017-12-22T13:24:40.000000Z 字数 21029 阅读 5046

网络流专题

OI


例题

网络流24题 方格取数

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=30*30+10,maxm=maxn*4,INF=0x3f3f3f3f;
  10. int n,m,S,T,ans;
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow;
  20. Node(){}
  21. Node(int x,int y,int cap):x(x),y(y),cap(cap){}
  22. }node[2*maxm];
  23. int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z) {
  25. node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int zz[maxn],dis[maxn];
  29. bool BFS() {
  30. int s=1,t=0,x,y,z;
  31. memset(dis,-1,sizeof(dis));
  32. zz[++t]=S;dis[S]=0;
  33. while(s<=t) {
  34. x=zz[s];s++;
  35. for(y=fir[x];y;y=nxt[y]) {
  36. z=node[y].y;
  37. if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
  38. dis[z]=dis[x]+1;
  39. zz[++t]=z;
  40. }
  41. }
  42. return dis[T]!=-1;
  43. }
  44. int DFS(int pos,int maxf) {
  45. if(pos==T||!maxf) return maxf;
  46. int now,z,rs=0;
  47. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  48. z=node[y].y;
  49. if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
  50. now=DFS(z,min(maxf,node[y].cap-node[y].flow));
  51. node[y].flow+=now; node[y^1].flow-=now;
  52. maxf-=now; rs+=now;
  53. }
  54. if(!rs) dis[pos]=-1;
  55. return rs;
  56. }
  57. int Dinic() {
  58. int rs=0;
  59. while(BFS()) {
  60. memcpy(cur,fir,sizeof(cur));
  61. rs+=DFS(S,INF);
  62. }
  63. return rs;
  64. }
  65. int main() {
  66. n=read(); m=read(); int x,p,pos;
  67. S=n*m+1; T=S+1;
  68. for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) {
  69. ans+=(x=read()); p=(i+j)&1; pos=(i-1)*m+j;
  70. if(!p) add(S,pos,x);
  71. else add(pos,T,x);
  72. if(i>1&&!p) add(pos,pos-m,INF);
  73. else if(i>1) add(pos-m,pos,INF);
  74. if(j>1&&!p) add(pos,pos-1,INF);
  75. else if(j>1) add(pos-1,pos,INF);
  76. }
  77. printf("%d",ans-Dinic());
  78. return 0;
  79. }

网络流24题 最长递增子序列

题目有毒,注意关于ans=1的情况的特判

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=1000+10,maxm=maxn*maxn/4+maxn,INF=0x3f3f3f3f;
  10. int n,a[maxn],f[maxn],ans,S,T;
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow;
  20. Node(){}
  21. Node(int x,int y,int cap):x(x),y(y),cap(cap){}
  22. }node[2*maxm];
  23. int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z) {
  25. node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int zz[maxn],dis[maxn];
  29. bool BFS() {
  30. int s=1,t=0,x,y,z;
  31. memset(dis,-1,sizeof(dis));
  32. zz[++t]=S;dis[S]=0;
  33. while(s<=t) {
  34. x=zz[s];s++;
  35. for(y=fir[x];y;y=nxt[y]) {
  36. z=node[y].y;
  37. if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
  38. dis[z]=dis[x]+1;
  39. zz[++t]=z;
  40. }
  41. }
  42. return dis[T]!=-1;
  43. }
  44. int DFS(int pos,int maxf) {
  45. if(pos==T||!maxf) return maxf;
  46. int now,z,rs=0;
  47. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  48. z=node[y].y;
  49. if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
  50. now=DFS(z,min(maxf,node[y].cap-node[y].flow));
  51. node[y].flow+=now; node[y^1].flow-=now;
  52. maxf-=now; rs+=now;
  53. }
  54. if(!rs) dis[pos]=-1;
  55. return rs;
  56. }
  57. int Dinic() {
  58. int rs=0;
  59. while(BFS()) {
  60. memcpy(cur,fir,sizeof(cur));
  61. rs+=DFS(S,INF);
  62. }
  63. return rs;
  64. }
  65. int main() {
  66. n=read(); int x;
  67. S=2*n+1; T=S+1;
  68. for(int i=1;i<=n;++i) {
  69. a[i]=read(); f[i]=1;
  70. for(int j=1;j<i;++j) if(a[i]>=a[j]) f[i]=max(f[i],f[j]+1);
  71. ans=max(f[i],ans);
  72. }
  73. if(ans==1) printf("1\n%d\n%d",n,n);
  74. else {
  75. printf("%d\n",ans);
  76. for(int i=1;i<=n;++i) {
  77. add(i,i+n,1);
  78. if(f[i]==1) add(S,i,1);
  79. else if(f[i]==ans) add(i+n,T,1);
  80. }
  81. for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(a[j]>=a[i]&&f[j]==f[i]+1) add(i+n,j,1);//
  82. printf("%d\n",Dinic());
  83. memset(fir,0,sizeof(fir)); e=1;
  84. for(int i=1;i<=n;++i) {
  85. x= i==1||i==n? INF:1;
  86. add(i,i+n,x);
  87. if(f[i]==1) add(S,i,i==1? x:1);
  88. else if(f[i]==ans) add(i+n,T,i==n? x:1);
  89. }
  90. for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(a[j]>=a[i]&&f[j]==f[i]+1) add(i+n,j,1);//
  91. printf("%d",Dinic());
  92. }
  93. return 0;
  94. }

网络流24题 最小路径覆盖

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=400+10,maxm=6010+maxn;
  10. int n,m,k,S,T,tot,ans,rb[maxn],rd[maxn];
  11. bool pl[maxn];int v[maxn];
  12. int aa;char cc;
  13. int read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. struct Node{
  20. int x,y,cap,flow;
  21. }node[2*maxm];
  22. int cur[maxn];
  23. int fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z) {
  25. node[++e].x=x;node[e].y=y;node[e].cap=z; nxt[e]=fir[x];fir[x]=e;
  26. node[++e].x=y;node[e].y=x;node[e].cap=0; nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int zz[maxn],dis[maxn],s=1,t=0;
  29. bool BFS() {
  30. memset(dis,-1,sizeof(dis));
  31. dis[S]=0; s=1,t=0;zz[++t]=S;
  32. int x,y;
  33. while(s<=t) {
  34. x=zz[s];s++;
  35. for(y=fir[x];y;y=nxt[y]) {
  36. if(node[y].flow>=node[y].cap||dis[node[y].y]!=-1) continue;
  37. dis[node[y].y]=dis[x]+1;
  38. zz[++t]=node[y].y;
  39. }
  40. }
  41. return dis[T]!=-1;
  42. }
  43. int DFS(int pos,int maxf) {
  44. if(pos==T||!maxf) return maxf;
  45. int rs=0,now;
  46. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  47. if(node[y].flow>=node[y].cap||dis[node[y].y]!=dis[node[y].x]+1) continue;
  48. now=DFS(node[y].y,min(maxf,node[y].cap-node[y].flow));
  49. node[y].flow+=now;
  50. node[y^1].flow-=now;
  51. rs+=now;
  52. maxf-=now;
  53. }
  54. if(!rs) dis[pos]=-1;
  55. return rs;
  56. }
  57. int Dinic() {
  58. int rs=0;
  59. while(BFS()) {
  60. memcpy(cur,fir,sizeof(fir));
  61. rs+=DFS(S,0x3f3f3f3f);
  62. }
  63. return rs;
  64. }
  65. int main() {
  66. n=read();m=read();tot=n;
  67. int x,y; S=2*n+1;T=S+1;
  68. for(int i=1;i<=n;++i) add(S,i,1),add(i+n,T,1);
  69. for(int i=1;i<=m;++i) {
  70. x=read();y=read();
  71. add(x,y+n,1);
  72. }
  73. ans=tot-Dinic();
  74. for(int i=2;i<=e;++i) {
  75. if(node[i].x<=n&&node[i].flow==1) {
  76. rb[node[i].x]=node[i].y-n;
  77. rd[node[i].y-n]=1;
  78. }
  79. }
  80. for(int i=1;i<=n;++i) if(!rd[i]){
  81. x=i;printf("%d",i);
  82. while(rb[x]) printf(" %d",x=rb[x]);
  83. printf("\n");
  84. }
  85. printf("%d",ans);
  86. return 0;
  87. }

网络流24题 魔术球

=>

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=1570*2+10,maxm=maxn*maxn,INF=0x3f3f3f3f;
  10. int S,T,n,rb[maxn],rd[maxn];
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow;
  20. Node(){}
  21. Node(int x,int y,int cap):x(x),y(y),cap(cap){}
  22. }node[2*maxm];
  23. int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z) {
  25. node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int zz[maxn],dis[maxn];
  29. bool BFS() {
  30. int s=1,t=0,x,y,z;
  31. memset(dis,-1,sizeof(dis));
  32. zz[++t]=S;dis[S]=0;
  33. while(s<=t) {
  34. x=zz[s];s++;
  35. for(y=fir[x];y;y=nxt[y]) {
  36. z=node[y].y;
  37. if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
  38. dis[z]=dis[x]+1;
  39. zz[++t]=z;
  40. }
  41. }
  42. return dis[T]!=-1;
  43. }
  44. int DFS(int pos,int maxf) {
  45. if(pos==T||!maxf) return maxf;
  46. int now,z,rs=0;
  47. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  48. z=node[y].y;
  49. if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
  50. now=DFS(z,min(maxf,node[y].cap-node[y].flow));
  51. node[y].flow+=now; node[y^1].flow-=now;
  52. maxf-=now; rs+=now;
  53. }
  54. if(!rs) dis[pos]=-1;
  55. return rs;
  56. }
  57. int Dinic() {
  58. int rs=0;
  59. while(BFS()) {
  60. memcpy(cur,fir,sizeof(cur));
  61. rs+=DFS(S,INF);
  62. }
  63. return rs;
  64. }
  65. bool ok(int x) {
  66. int xx=sqrt(x);
  67. return xx*xx==x;
  68. }
  69. bool check(int x) {
  70. S=2*x+1;T=S+1; e=1;
  71. memset(fir,0,sizeof(fir));
  72. for(int i=1;i<=x;++i) for(int j=i+1;j<=x+1;++j)
  73. if(ok(i+j)) add(i,j+x,1);
  74. for(int i=1;i<=x;++i) add(S,i,1),add(i+x,T,1);
  75. return x-Dinic()<=n;
  76. }
  77. int main() {
  78. n=read();int l=n,r=1570,mid,x;
  79. while(l<r-1) {
  80. mid=(l+r)>>1;
  81. if(check(mid)) l=mid;
  82. else r=mid;
  83. }
  84. printf("%d\n",l);check(l);
  85. for(int i=2;i<=e;++i) {
  86. if(node[i].x<=l&&node[i].flow==1) {
  87. rb[node[i].x]=node[i].y-l;
  88. rd[node[i].y-l]=1;
  89. }
  90. }
  91. for(int i=1;i<=l;++i) if(!rd[i]){
  92. x=i;printf("%d",i);
  93. while(rb[x]) printf(" %d",x=rb[x]);
  94. printf("\n");
  95. }
  96. return 0;
  97. }

网络流24题 餐巾计划

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=2000+10,maxm=4*maxn,INF=0x3f3f3f3f;
  10. int n,P,M,F,N,R,S,T;
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow,w;
  20. Node(){}
  21. Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){}
  22. }node[2*maxm];
  23. int fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z,int w) {
  25. node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int from[maxn],zz[maxn],dis[maxn];
  29. bool vis[maxn];
  30. bool spfa() {
  31. int s=1,t=0,x,y,z;
  32. memset(dis,0x3f3f3f3f,sizeof(dis));
  33. memset(zz,0,sizeof(zz));
  34. zz[++t]=S;dis[S]=0;vis[S]=1;
  35. while(s<=t) {
  36. x=zz[s%maxn];s++;vis[x]=0;
  37. for(y=fir[x];y;y=nxt[y]) {
  38. if(node[y].flow>=node[y].cap||dis[z=node[y].y]<=dis[x]+node[y].w) continue;
  39. dis[z]=dis[x]+node[y].w; from[z]=y;
  40. if(!vis[z]) {
  41. vis[z]=1;t++;
  42. zz[t%maxn]=z;
  43. }
  44. }
  45. }
  46. return dis[T]!=INF;
  47. }
  48. int MCMF() {
  49. int rs=0,now;
  50. while(spfa()) {
  51. now=INF;
  52. for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
  53. for(int i=T;i!=S;i=node[from[i]].x) {
  54. node[from[i]].flow+=now;
  55. node[from[i]^1].flow-=now;
  56. rs+=node[from[i]].w*now;
  57. }
  58. }
  59. return rs;
  60. }
  61. int main() {
  62. n=read(); S=2*n+1;T=S+1; int x;
  63. P=read();M=read();F=read();N=read();R=read();
  64. for(int i=1;i<=n;++i) {
  65. add(S,i+n,INF,P);
  66. if(i+1<=n) add(i,i+1,INF,0);
  67. if(i+M<=n) add(i,i+M+n,INF,F);
  68. if(i+N<=n) add(i,i+N+n,INF,R);
  69. }
  70. for(int i=1;i<=n;++i) {
  71. x=read();
  72. add(S,i,x,0);
  73. add(i+n,T,x,0);
  74. }
  75. printf("%d",MCMF());
  76. return 0;
  77. }

网络流24题 太空飞行计划

loj的数据有毒,注意输入方式,特别是不要用读入优化,否则可能WA和RE

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const int maxn=100+10,maxm=maxn*maxn,INF=0x3f3f3f3f;
  11. int n,m,ans,S,T;
  12. bool usd[maxn];
  13. char cc;
  14. struct Node{
  15. int x,y,cap,flow;
  16. Node(){}
  17. Node(int x,int y,int cap):x(x),y(y),cap(cap){}
  18. }node[2*maxm];
  19. int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
  20. void add(int x,int y,int z) {
  21. node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
  22. node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
  23. }
  24. int zz[maxn],dis[maxn];
  25. bool BFS() {
  26. int s=1,t=0,x,y,z;
  27. memset(dis,-1,sizeof(dis));
  28. zz[++t]=S;dis[S]=0;
  29. while(s<=t) {
  30. x=zz[s];s++;
  31. for(y=fir[x];y;y=nxt[y]) {
  32. z=node[y].y;
  33. if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
  34. dis[z]=dis[x]+1;
  35. zz[++t]=z;
  36. }
  37. }
  38. return dis[T]!=-1;
  39. }
  40. int DFS(int pos,int maxf) {
  41. if(pos==T||!maxf) return maxf;
  42. int now,z,rs=0;
  43. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  44. z=node[y].y;
  45. if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
  46. now=DFS(z,min(maxf,node[y].cap-node[y].flow));
  47. node[y].flow+=now; node[y^1].flow-=now;
  48. maxf-=now; rs+=now;
  49. }
  50. if(!rs) dis[pos]=-1;
  51. return rs;
  52. }
  53. int Dinic() {
  54. int rs=0;
  55. while(BFS()) {
  56. memcpy(cur,fir,sizeof(cur));
  57. rs+=DFS(S,INF);
  58. }
  59. return rs;
  60. }
  61. int main() {
  62. scanf("%d%d",&n,&m);
  63. S=n+m+1; T=S+1; int x;
  64. for(int i=1;i<=n;++i) {
  65. scanf("%d",&x); ans+=x;
  66. add(S,i,x);
  67. do{
  68. cc=getchar();
  69. if(cc=='\n'||cc=='\r'||cc==EOF) break;
  70. scanf("%d",&x);add(i,n+x,INF);
  71. }while(cc!='\n'&&cc!='\r'&&cc!=EOF);
  72. }
  73. for(int i=1;i<=m;++i) scanf("%d",&x),add(i+n,T,x);
  74. ans-=Dinic();
  75. for(int i=1;i<=n;++i) if(~dis[i]) {
  76. printf("%d ",i);
  77. for(int y=fir[i];y;y=nxt[y]) if(node[y].y<=n+m) usd[node[y].y-n]=1;
  78. }
  79. printf("\n");
  80. for(int i=1;i<=m;++i) if(usd[i]) printf("%d ",i);
  81. printf("\n%d",ans);
  82. return 0;
  83. }

网络流24题 最长k可重区间集

题面有毒,他区间长度的计算方式是这样的:

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=1000+10,maxm=2*maxn,INF=0x3f3f3f3f;
  10. int n,k,S,T,p[maxn],tot;
  11. struct Li{
  12. int l,r;
  13. }line[maxn];
  14. int aa;char cc;
  15. int read() {
  16. aa=0;cc=getchar();
  17. while(cc<'0'||cc>'9') cc=getchar();
  18. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  19. return aa;
  20. }
  21. struct Node{
  22. int x,y,cap,flow,w;
  23. Node(){}
  24. Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){}
  25. }node[2*maxm];
  26. int fir[maxn],nxt[2*maxm],e=1;
  27. void add(int x,int y,int z,int w) {
  28. node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
  29. node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
  30. // printf("add: %d->%d z:%d w:%d\n",x,y,z,w);
  31. }
  32. int from[maxn],zz[maxn],dis[maxn];
  33. bool vis[maxn];
  34. bool spfa() {
  35. int s=1,t=0,x,y,z;
  36. memset(dis,-1,sizeof(dis));
  37. memset(zz,0,sizeof(zz));
  38. zz[++t]=S;dis[S]=0;vis[S]=1;
  39. while(s<=t) {
  40. x=zz[s%maxn];s++;vis[x]=0;
  41. for(y=fir[x];y;y=nxt[y]) {
  42. if(node[y].flow>=node[y].cap||dis[z=node[y].y]>=dis[x]+node[y].w) continue;
  43. dis[z]=dis[x]+node[y].w; from[z]=y;
  44. if(!vis[z]) {
  45. vis[z]=1;t++;
  46. zz[t%maxn]=z;
  47. }
  48. }
  49. }
  50. return dis[T]!=-1;
  51. }
  52. int MCMF() {
  53. int rs=0,now;
  54. while(spfa()) {
  55. now=INF;
  56. for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
  57. for(int i=T;i!=S;i=node[from[i]].x) {
  58. node[from[i]].flow+=now;
  59. node[from[i]^1].flow-=now;
  60. rs+=node[from[i]].w*now;
  61. }
  62. }
  63. return rs;
  64. }
  65. int ef(int x) {
  66. int l=1,r=tot,mid;
  67. while(l<=r) {
  68. mid=(l+r)>>1;
  69. if(p[mid]==x) return mid;
  70. if(p[mid]<x) l=mid+1;
  71. else r=mid-1;
  72. }
  73. }
  74. int main() {
  75. n=read(); k=read();
  76. for(int i=1;i<=n;++i) {
  77. p[++tot]=line[i].l=read();
  78. p[++tot]=line[i].r=read();
  79. if(line[i].l>line[i].r) swap(line[i].l,line[i].r);
  80. }
  81. sort(p+1,p+tot+1);
  82. tot=unique(p+1,p+tot+1)-(p+1);
  83. for(int i=1;i<=n;++i) add(ef(line[i].l),ef(line[i].r),1,line[i].r-line[i].l);
  84. for(int i=1;i<tot;++i) add(i,i+1,k,0);
  85. S=tot+1; T=S+1;
  86. add(S,1,k,0); add(tot,T,k,0);
  87. printf("%d",MCMF());
  88. return 0;
  89. }

bzoj3442 学习小组

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=200+10,maxm=20000+10,INF=0x3f3f3f3f;
  10. int n,m,k,C[maxn],F[maxn],S,T;
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow,w;
  20. Node(){}
  21. Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){flow=0;}
  22. }node[2*maxm];
  23. int fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z,int w) {
  25. node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int from[maxn],zz[maxn],dis[maxn];
  29. bool vis[maxn];
  30. bool spfa() {
  31. int s=1,t=0,x,y,z;
  32. memset(dis,0x3f3f3f3f,sizeof(dis));
  33. memset(zz,0,sizeof(zz));
  34. zz[++t]=S;dis[S]=0;vis[S]=1;
  35. while(s<=t) {
  36. x=zz[s%maxn];s++;vis[x]=0;
  37. for(y=fir[x];y;y=nxt[y]) {
  38. if(node[y].flow>=node[y].cap||dis[z=node[y].y]<=dis[x]+node[y].w) continue;
  39. dis[z]=dis[x]+node[y].w; from[z]=y;
  40. if(!vis[z]) {
  41. vis[z]=1;t++;
  42. zz[t%maxn]=z;
  43. }
  44. }
  45. }
  46. return dis[T]!=INF;
  47. }
  48. int MCMF() {
  49. int rs=0,now;
  50. while(spfa()) {
  51. now=INF;
  52. for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
  53. for(int i=T;i!=S;i=node[from[i]].x) {
  54. node[from[i]].flow+=now;
  55. node[from[i]^1].flow-=now;
  56. rs+=node[from[i]].w*now;
  57. }
  58. }
  59. return rs;
  60. }
  61. int main() {
  62. n=read(); m=read(); k=read();
  63. S=n+m+1;T=S+1; int x;
  64. for(int i=1;i<=n;++i) {
  65. add(S,i,k,0);
  66. add(i,T,k-1,0);
  67. }
  68. for(int i=1;i<=m;++i) C[i]=read();
  69. for(int i=1;i<=m;++i) F[i]=read();
  70. for(int i=1;i<=m;++i)
  71. for(int j=1;j<=n;++j)
  72. add(n+i,T,1,(2*j-1)*C[i]-F[i]);
  73. for(int i=1;i<=n;++i)
  74. for(int j=1;j<=m;++j) {
  75. scanf("%1d",&x);
  76. if(x) add(i,n+j,1,0);
  77. }
  78. printf("%d",MCMF());
  79. return 0;
  80. }

bzoj1061 志愿者招募

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=1000+10,maxm=30*maxn,INF=0x3f3f3f3f;
  10. int n,m,S,T,p[maxn];
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow,w;
  20. Node(){}
  21. Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){flow=0;}
  22. }node[2*maxm];
  23. int fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z,int w) {
  25. node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int from[maxn],zz[maxn],dis[maxn];
  29. bool vis[maxn];
  30. bool spfa() {
  31. int s=1,t=0,x,y,z;
  32. memset(dis,0x3f3f3f3f,sizeof(dis));
  33. memset(zz,0,sizeof(zz));
  34. zz[++t]=S;dis[S]=0;vis[S]=1;
  35. while(s<=t) {
  36. x=zz[s%maxn];s++;vis[x]=0;
  37. for(y=fir[x];y;y=nxt[y]) {
  38. if(node[y].flow>=node[y].cap||dis[z=node[y].y]<=dis[x]+node[y].w) continue;
  39. dis[z]=dis[x]+node[y].w; from[z]=y;
  40. if(!vis[z]) {
  41. vis[z]=1;t++;
  42. zz[t%maxn]=z;
  43. }
  44. }
  45. }
  46. return dis[T]!=INF;
  47. }
  48. int MCMF() {
  49. int rs=0,now;
  50. while(spfa()) {
  51. now=INF;
  52. for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
  53. for(int i=T;i!=S;i=node[from[i]].x) {
  54. node[from[i]].flow+=now;
  55. node[from[i]^1].flow-=now;
  56. rs+=node[from[i]].w*now;
  57. }
  58. }
  59. return rs;
  60. }
  61. int main() {
  62. n=read(); m=read();
  63. S=n+2;T=S+1;
  64. for(int i=1;i<=n;++i) p[i]=read();
  65. for(int i=1;i<=n+1;++i) {
  66. if(p[i-1]-p[i]>0) add(S,i,p[i-1]-p[i],0);
  67. else add(i,T,p[i]-p[i-1],0);
  68. }
  69. int l,r,c;
  70. for(int i=1;i<=m;++i) {
  71. l=read(); r=read(); c=read();
  72. add(r+1,l,INF,c);
  73. }
  74. for(int i=1;i<=n;++i) add(i,i+1,INF,0);
  75. printf("%d",MCMF());
  76. return 0;
  77. }

vijos1891 学姐的逛街计划

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=400+10,maxm=4*maxn,INF=0x3f3f3f3f;
  10. int n,k,S,T,c[2*maxn];
  11. int aa;char cc;
  12. int read() {
  13. aa=0;cc=getchar();
  14. while(cc<'0'||cc>'9') cc=getchar();
  15. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  16. return aa;
  17. }
  18. struct Node{
  19. int x,y,cap,flow,w;
  20. Node(){}
  21. Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){}
  22. }node[2*maxm];
  23. int fir[maxn],nxt[2*maxm],e=1;
  24. void add(int x,int y,int z,int w) {
  25. node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
  26. node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
  27. }
  28. int from[maxn],zz[maxn],dis[maxn];
  29. bool vis[maxn];
  30. bool spfa() {
  31. int s=1,t=0,x,y,z;
  32. memset(dis,-1,sizeof(dis));
  33. memset(zz,0,sizeof(zz));
  34. zz[++t]=S;dis[S]=0;vis[S]=1;
  35. while(s<=t) {
  36. x=zz[s%maxn];s++;vis[x]=0;
  37. for(y=fir[x];y;y=nxt[y]) {
  38. if(node[y].flow>=node[y].cap||dis[z=node[y].y]>=dis[x]+node[y].w) continue;
  39. dis[z]=dis[x]+node[y].w; from[z]=y;
  40. if(!vis[z]) {
  41. vis[z]=1;t++;
  42. zz[t%maxn]=z;
  43. }
  44. }
  45. }
  46. return dis[T]!=-1;
  47. }
  48. int MCMF() {
  49. int rs=0,now;
  50. while(spfa()) {
  51. now=INF;
  52. for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
  53. for(int i=T;i!=S;i=node[from[i]].x) {
  54. node[from[i]].flow+=now;
  55. node[from[i]^1].flow-=now;
  56. rs+=node[from[i]].w*now;
  57. }
  58. }
  59. return rs;
  60. }
  61. int main() {
  62. n=read(); k=read();
  63. S=2*n+2;T=S+1;
  64. for(int i=1;i<=3*n;++i) c[i]=read();
  65. for(int i=1;i<=n;++i) add(i,i+n,1,c[i+n]);
  66. for(int i=1;i<2*n;++i) add(i,i+1,k,0);
  67. for(int i=1;i<=n;++i) add(2*n+1,i,1,c[i]);
  68. for(int i=n+1;i<=2*n;++i) add(i,T,1,c[i+n]);
  69. add(S,2*n+1,k,0);
  70. printf("%d",MCMF());
  71. return 0;
  72. }

test 1212night A

题面有毒,汇点应该是n.

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. #define ll long long
  10. const ll maxn=200+10,maxm=1000+10,INF=1e9;
  11. ll n,m,S,T,ind[maxn];
  12. ll ans;
  13. ll aa;char cc;
  14. ll read() {
  15. aa=0;cc=getchar();
  16. while(cc<'0'||cc>'9') cc=getchar();
  17. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  18. return aa;
  19. }
  20. struct Node{
  21. int x,y;ll cap,flow,w;
  22. Node(){}
  23. Node(int x,int y,ll cap,ll w):x(x),y(y),cap(cap),w(w){flow=0;}
  24. }node[2*maxm];
  25. int fir[maxn],nxt[2*maxm],e=1;
  26. void add(int x,int y,ll z,ll w) {
  27. // printf("add:%d -> %d cap:%lld w:%lld\n",x,y,z,w);
  28. node[++e]=Node(x,y,z,w); nxt[e]=fir[x]; fir[x]=e;
  29. node[++e]=Node(y,x,0,-w); nxt[e]=fir[y];fir[y]=e;
  30. }
  31. ll zz[maxn],dis[maxn],from[maxn];
  32. bool vis[maxn];
  33. bool spfa() {
  34. for(int i=1;i<=n+2;++i) dis[i]=INF,from[i]=0;
  35. int s=1,t=0,x,y,z,o;
  36. dis[S]=0; zz[++t]=S;vis[S]=1;
  37. while(s<=t) {
  38. x=zz[s%maxn];s++; vis[x]=0;
  39. for(y=fir[x];y;y=nxt[y]) {
  40. z=node[y].y;
  41. if(node[y].flow>=node[y].cap||dis[z]<=dis[x]+node[y].w) continue;
  42. dis[z]=dis[x]+node[y].w;
  43. from[z]=y;
  44. if(!vis[z]) {
  45. vis[z]=1; t++;
  46. zz[t%maxn]=z;
  47. }
  48. }
  49. }
  50. return dis[T]<INF;
  51. }
  52. ll MCMF() {
  53. ll rs=0,now;
  54. while(spfa()) {
  55. now=INF;
  56. for(int x=T;x!=S;x=node[from[x]].x) now=min(now,node[from[x]].cap-node[from[x]].flow);
  57. for(int x=T;x!=S;x=node[from[x]].x) {
  58. rs+=now*node[from[x]].w;
  59. node[from[x]].flow+=now;
  60. node[from[x]^1].flow-=now;
  61. }
  62. }
  63. return rs;
  64. }
  65. int main() {
  66. n=read(); m=read();
  67. int x,y,f,c; S=n+1;T=n+2;
  68. for(int i=1;i<=m;++i) {
  69. x=read(); y=read(); c=read(); f=read();
  70. ind[y]+=f; ind[x]-=f;
  71. if(f<=c) {
  72. add(y,x,f,1);
  73. if(f!=c) add(x,y,c-f,1);
  74. add(x,y,INF,2);
  75. }
  76. else {
  77. ans+=f-c;
  78. add(y,x,f-c,0);
  79. add(y,x,c,1);
  80. add(x,y,INF,2);
  81. }
  82. }
  83. for(int i=1;i<=n;++i) {
  84. if(ind[i]<0) add(i,T,-ind[i],0);
  85. else if(ind[i]>0) add(S,i,ind[i],0);
  86. }
  87. add(n,1,INF,0);
  88. ans+=MCMF();
  89. printf("%lld",ans);
  90. return 0;
  91. }

test 1213 T2 百步穿杨

数据第4、5个点有毒。

  1. //Serene
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<cmath>
  8. using namespace std;
  9. const int maxn=2e4+10,INF=0x3f3f3f3f;
  10. int n,m,S,T,ans;
  11. char c[57][57];
  12. int aa;char cc;
  13. int read() {
  14. aa=0;cc=getchar();
  15. while(cc<'0'||cc>'9') cc=getchar();
  16. while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
  17. return aa;
  18. }
  19. int is_ok(char x) {
  20. if(x=='.') return 0;
  21. if(x>='0'&&x<='9') return x-'0';
  22. if(x=='A'||x=='V'||x=='<'||x=='>') return -1;
  23. return -2;
  24. }
  25. struct Node{
  26. int x,y,cap,flow;
  27. Node(){}
  28. Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;}
  29. }node[6*maxn];
  30. int cur[maxn],fir[maxn],nxt[6*maxn],e=1;
  31. void add(int x,int y,int z) {
  32. // printf("add:%d -> %d cap:%d\n",x,y,z);
  33. node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
  34. node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
  35. }
  36. int get_id(int x,int y,int p) {
  37. return (x-1)*m+y+p*n*m;
  38. }
  39. void init() {
  40. int xx,yy,dx,dy,nowmax,num,p;
  41. for(int i=0;i<=n+1;++i) c[i][0]=c[i][m+1]='#';
  42. for(int i=0;i<=m+1;++i) c[0][i]=c[n+1][i]='#';
  43. for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(is_ok(c[i][j])==-1){
  44. switch(c[i][j]) {
  45. case 'A':dx=-1;dy=0;p=1;break;
  46. case 'V':dx=1;dy=0; p=1;break;
  47. case '<':dx=0;dy=-1;p=0;break;
  48. case '>':dx=0;dy=1; p=0;break;
  49. }
  50. xx=i+dx; yy=j+dy;
  51. nowmax=0;
  52. while((num=is_ok(c[xx][yy]))>=0) {
  53. if(num>nowmax) nowmax=num;
  54. xx+=dx; yy+=dy;
  55. }
  56. if(!nowmax) continue; ans+=nowmax;
  57. xx=i; yy=j; num=0;
  58. do{
  59. if(!p) add(get_id(xx,yy,0),get_id(xx+dx,yy+dy,0),nowmax-num);
  60. else add(get_id(xx+dx,yy+dy,1),get_id(xx,yy,1),nowmax-num);
  61. xx+=dx; yy+=dy;
  62. }while((num=is_ok(c[xx][yy]))!=nowmax);
  63. if(!p) add(S,get_id(i,j,0),INF);
  64. else add(get_id(i,j,1),T,INF);
  65. }
  66. for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) add(get_id(i,j,0),get_id(i,j,1),INF);
  67. }
  68. int dis[maxn],zz[maxn];
  69. bool BFS() {
  70. memset(dis,-1,sizeof(dis));
  71. int s=1,t=0,x,y,z;
  72. zz[++t]=S; dis[S]=1;
  73. while(s<=t) {
  74. x=zz[s++];
  75. for(y=fir[x];y;y=nxt[y]) {
  76. if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue;
  77. dis[z]=dis[x]+1;
  78. zz[++t]=z;
  79. }
  80. }
  81. return dis[T]!=-1;
  82. }
  83. int DFS(int pos,int maxf) {
  84. if(pos==T||!maxf) return maxf;
  85. int rs=0,now,z;
  86. for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
  87. if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
  88. now=DFS(z,min(maxf,node[y].cap-node[y].flow));
  89. node[y].flow+=now; node[y^1].flow-=now;
  90. rs+=now;maxf-=now;
  91. }
  92. if(!rs) dis[pos]=-1;
  93. return rs;
  94. }
  95. int Dinic() {
  96. int rs=0;
  97. while(BFS()) {
  98. memcpy(cur,fir,sizeof(fir));
  99. rs+=DFS(S,INF);
  100. }
  101. return rs;
  102. }
  103. int main() {
  104. freopen("archery.in","r",stdin);
  105. freopen("archery.out","w",stdout);
  106. n=read(); m=read();
  107. for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) do c[i][j]=getchar();while(is_ok(c[i][j])<-1);
  108. S=2*n*m+1; T=S+1;
  109. init();
  110. ans-=Dinic();
  111. printf("%d\n",ans);
  112. return 0;
  113. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注