@shixinyi
2017-12-22T13:24:40.000000Z
字数 21029
阅读 5046
OI
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=30*30+10,maxm=maxn*4,INF=0x3f3f3f3f;
int n,m,S,T,ans;
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow;
Node(){}
Node(int x,int y,int cap):x(x),y(y),cap(cap){}
}node[2*maxm];
int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z) {
node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
}
int zz[maxn],dis[maxn];
bool BFS() {
int s=1,t=0,x,y,z;
memset(dis,-1,sizeof(dis));
zz[++t]=S;dis[S]=0;
while(s<=t) {
x=zz[s];s++;
for(y=fir[x];y;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return dis[T]!=-1;
}
int DFS(int pos,int maxf) {
if(pos==T||!maxf) return maxf;
int now,z,rs=0;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=DFS(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now; node[y^1].flow-=now;
maxf-=now; rs+=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
int Dinic() {
int rs=0;
while(BFS()) {
memcpy(cur,fir,sizeof(cur));
rs+=DFS(S,INF);
}
return rs;
}
int main() {
n=read(); m=read(); int x,p,pos;
S=n*m+1; T=S+1;
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) {
ans+=(x=read()); p=(i+j)&1; pos=(i-1)*m+j;
if(!p) add(S,pos,x);
else add(pos,T,x);
if(i>1&&!p) add(pos,pos-m,INF);
else if(i>1) add(pos-m,pos,INF);
if(j>1&&!p) add(pos,pos-1,INF);
else if(j>1) add(pos-1,pos,INF);
}
printf("%d",ans-Dinic());
return 0;
}
题目有毒,注意关于ans=1的情况的特判
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1000+10,maxm=maxn*maxn/4+maxn,INF=0x3f3f3f3f;
int n,a[maxn],f[maxn],ans,S,T;
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow;
Node(){}
Node(int x,int y,int cap):x(x),y(y),cap(cap){}
}node[2*maxm];
int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z) {
node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
}
int zz[maxn],dis[maxn];
bool BFS() {
int s=1,t=0,x,y,z;
memset(dis,-1,sizeof(dis));
zz[++t]=S;dis[S]=0;
while(s<=t) {
x=zz[s];s++;
for(y=fir[x];y;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return dis[T]!=-1;
}
int DFS(int pos,int maxf) {
if(pos==T||!maxf) return maxf;
int now,z,rs=0;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=DFS(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now; node[y^1].flow-=now;
maxf-=now; rs+=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
int Dinic() {
int rs=0;
while(BFS()) {
memcpy(cur,fir,sizeof(cur));
rs+=DFS(S,INF);
}
return rs;
}
int main() {
n=read(); int x;
S=2*n+1; T=S+1;
for(int i=1;i<=n;++i) {
a[i]=read(); f[i]=1;
for(int j=1;j<i;++j) if(a[i]>=a[j]) f[i]=max(f[i],f[j]+1);
ans=max(f[i],ans);
}
if(ans==1) printf("1\n%d\n%d",n,n);
else {
printf("%d\n",ans);
for(int i=1;i<=n;++i) {
add(i,i+n,1);
if(f[i]==1) add(S,i,1);
else if(f[i]==ans) add(i+n,T,1);
}
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);//
printf("%d\n",Dinic());
memset(fir,0,sizeof(fir)); e=1;
for(int i=1;i<=n;++i) {
x= i==1||i==n? INF:1;
add(i,i+n,x);
if(f[i]==1) add(S,i,i==1? x:1);
else if(f[i]==ans) add(i+n,T,i==n? x:1);
}
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);//
printf("%d",Dinic());
}
return 0;
}
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=400+10,maxm=6010+maxn;
int n,m,k,S,T,tot,ans,rb[maxn],rd[maxn];
bool pl[maxn];int v[maxn];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow;
}node[2*maxm];
int cur[maxn];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z) {
node[++e].x=x;node[e].y=y;node[e].cap=z; nxt[e]=fir[x];fir[x]=e;
node[++e].x=y;node[e].y=x;node[e].cap=0; nxt[e]=fir[y];fir[y]=e;
}
int zz[maxn],dis[maxn],s=1,t=0;
bool BFS() {
memset(dis,-1,sizeof(dis));
dis[S]=0; s=1,t=0;zz[++t]=S;
int x,y;
while(s<=t) {
x=zz[s];s++;
for(y=fir[x];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[node[y].y]!=-1) continue;
dis[node[y].y]=dis[x]+1;
zz[++t]=node[y].y;
}
}
return dis[T]!=-1;
}
int DFS(int pos,int maxf) {
if(pos==T||!maxf) return maxf;
int rs=0,now;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[node[y].y]!=dis[node[y].x]+1) continue;
now=DFS(node[y].y,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now;
node[y^1].flow-=now;
rs+=now;
maxf-=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
int Dinic() {
int rs=0;
while(BFS()) {
memcpy(cur,fir,sizeof(fir));
rs+=DFS(S,0x3f3f3f3f);
}
return rs;
}
int main() {
n=read();m=read();tot=n;
int x,y; S=2*n+1;T=S+1;
for(int i=1;i<=n;++i) add(S,i,1),add(i+n,T,1);
for(int i=1;i<=m;++i) {
x=read();y=read();
add(x,y+n,1);
}
ans=tot-Dinic();
for(int i=2;i<=e;++i) {
if(node[i].x<=n&&node[i].flow==1) {
rb[node[i].x]=node[i].y-n;
rd[node[i].y-n]=1;
}
}
for(int i=1;i<=n;++i) if(!rd[i]){
x=i;printf("%d",i);
while(rb[x]) printf(" %d",x=rb[x]);
printf("\n");
}
printf("%d",ans);
return 0;
}
=>
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1570*2+10,maxm=maxn*maxn,INF=0x3f3f3f3f;
int S,T,n,rb[maxn],rd[maxn];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow;
Node(){}
Node(int x,int y,int cap):x(x),y(y),cap(cap){}
}node[2*maxm];
int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z) {
node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
}
int zz[maxn],dis[maxn];
bool BFS() {
int s=1,t=0,x,y,z;
memset(dis,-1,sizeof(dis));
zz[++t]=S;dis[S]=0;
while(s<=t) {
x=zz[s];s++;
for(y=fir[x];y;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return dis[T]!=-1;
}
int DFS(int pos,int maxf) {
if(pos==T||!maxf) return maxf;
int now,z,rs=0;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=DFS(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now; node[y^1].flow-=now;
maxf-=now; rs+=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
int Dinic() {
int rs=0;
while(BFS()) {
memcpy(cur,fir,sizeof(cur));
rs+=DFS(S,INF);
}
return rs;
}
bool ok(int x) {
int xx=sqrt(x);
return xx*xx==x;
}
bool check(int x) {
S=2*x+1;T=S+1; e=1;
memset(fir,0,sizeof(fir));
for(int i=1;i<=x;++i) for(int j=i+1;j<=x+1;++j)
if(ok(i+j)) add(i,j+x,1);
for(int i=1;i<=x;++i) add(S,i,1),add(i+x,T,1);
return x-Dinic()<=n;
}
int main() {
n=read();int l=n,r=1570,mid,x;
while(l<r-1) {
mid=(l+r)>>1;
if(check(mid)) l=mid;
else r=mid;
}
printf("%d\n",l);check(l);
for(int i=2;i<=e;++i) {
if(node[i].x<=l&&node[i].flow==1) {
rb[node[i].x]=node[i].y-l;
rd[node[i].y-l]=1;
}
}
for(int i=1;i<=l;++i) if(!rd[i]){
x=i;printf("%d",i);
while(rb[x]) printf(" %d",x=rb[x]);
printf("\n");
}
return 0;
}
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=2000+10,maxm=4*maxn,INF=0x3f3f3f3f;
int n,P,M,F,N,R,S,T;
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow,w;
Node(){}
Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){}
}node[2*maxm];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z,int w) {
node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
}
int from[maxn],zz[maxn],dis[maxn];
bool vis[maxn];
bool spfa() {
int s=1,t=0,x,y,z;
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(zz,0,sizeof(zz));
zz[++t]=S;dis[S]=0;vis[S]=1;
while(s<=t) {
x=zz[s%maxn];s++;vis[x]=0;
for(y=fir[x];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[z=node[y].y]<=dis[x]+node[y].w) continue;
dis[z]=dis[x]+node[y].w; from[z]=y;
if(!vis[z]) {
vis[z]=1;t++;
zz[t%maxn]=z;
}
}
}
return dis[T]!=INF;
}
int MCMF() {
int rs=0,now;
while(spfa()) {
now=INF;
for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
for(int i=T;i!=S;i=node[from[i]].x) {
node[from[i]].flow+=now;
node[from[i]^1].flow-=now;
rs+=node[from[i]].w*now;
}
}
return rs;
}
int main() {
n=read(); S=2*n+1;T=S+1; int x;
P=read();M=read();F=read();N=read();R=read();
for(int i=1;i<=n;++i) {
add(S,i+n,INF,P);
if(i+1<=n) add(i,i+1,INF,0);
if(i+M<=n) add(i,i+M+n,INF,F);
if(i+N<=n) add(i,i+N+n,INF,R);
}
for(int i=1;i<=n;++i) {
x=read();
add(S,i,x,0);
add(i+n,T,x,0);
}
printf("%d",MCMF());
return 0;
}
loj的数据有毒,注意输入方式,特别是不要用读入优化,否则可能WA和RE
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=100+10,maxm=maxn*maxn,INF=0x3f3f3f3f;
int n,m,ans,S,T;
bool usd[maxn];
char cc;
struct Node{
int x,y,cap,flow;
Node(){}
Node(int x,int y,int cap):x(x),y(y),cap(cap){}
}node[2*maxm];
int cur[maxn],fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z) {
node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
}
int zz[maxn],dis[maxn];
bool BFS() {
int s=1,t=0,x,y,z;
memset(dis,-1,sizeof(dis));
zz[++t]=S;dis[S]=0;
while(s<=t) {
x=zz[s];s++;
for(y=fir[x];y;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return dis[T]!=-1;
}
int DFS(int pos,int maxf) {
if(pos==T||!maxf) return maxf;
int now,z,rs=0;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
z=node[y].y;
if(dis[z]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=DFS(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now; node[y^1].flow-=now;
maxf-=now; rs+=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
int Dinic() {
int rs=0;
while(BFS()) {
memcpy(cur,fir,sizeof(cur));
rs+=DFS(S,INF);
}
return rs;
}
int main() {
scanf("%d%d",&n,&m);
S=n+m+1; T=S+1; int x;
for(int i=1;i<=n;++i) {
scanf("%d",&x); ans+=x;
add(S,i,x);
do{
cc=getchar();
if(cc=='\n'||cc=='\r'||cc==EOF) break;
scanf("%d",&x);add(i,n+x,INF);
}while(cc!='\n'&&cc!='\r'&&cc!=EOF);
}
for(int i=1;i<=m;++i) scanf("%d",&x),add(i+n,T,x);
ans-=Dinic();
for(int i=1;i<=n;++i) if(~dis[i]) {
printf("%d ",i);
for(int y=fir[i];y;y=nxt[y]) if(node[y].y<=n+m) usd[node[y].y-n]=1;
}
printf("\n");
for(int i=1;i<=m;++i) if(usd[i]) printf("%d ",i);
printf("\n%d",ans);
return 0;
}
题面有毒,他区间长度的计算方式是这样的:
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1000+10,maxm=2*maxn,INF=0x3f3f3f3f;
int n,k,S,T,p[maxn],tot;
struct Li{
int l,r;
}line[maxn];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow,w;
Node(){}
Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){}
}node[2*maxm];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z,int w) {
node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
// printf("add: %d->%d z:%d w:%d\n",x,y,z,w);
}
int from[maxn],zz[maxn],dis[maxn];
bool vis[maxn];
bool spfa() {
int s=1,t=0,x,y,z;
memset(dis,-1,sizeof(dis));
memset(zz,0,sizeof(zz));
zz[++t]=S;dis[S]=0;vis[S]=1;
while(s<=t) {
x=zz[s%maxn];s++;vis[x]=0;
for(y=fir[x];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[z=node[y].y]>=dis[x]+node[y].w) continue;
dis[z]=dis[x]+node[y].w; from[z]=y;
if(!vis[z]) {
vis[z]=1;t++;
zz[t%maxn]=z;
}
}
}
return dis[T]!=-1;
}
int MCMF() {
int rs=0,now;
while(spfa()) {
now=INF;
for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
for(int i=T;i!=S;i=node[from[i]].x) {
node[from[i]].flow+=now;
node[from[i]^1].flow-=now;
rs+=node[from[i]].w*now;
}
}
return rs;
}
int ef(int x) {
int l=1,r=tot,mid;
while(l<=r) {
mid=(l+r)>>1;
if(p[mid]==x) return mid;
if(p[mid]<x) l=mid+1;
else r=mid-1;
}
}
int main() {
n=read(); k=read();
for(int i=1;i<=n;++i) {
p[++tot]=line[i].l=read();
p[++tot]=line[i].r=read();
if(line[i].l>line[i].r) swap(line[i].l,line[i].r);
}
sort(p+1,p+tot+1);
tot=unique(p+1,p+tot+1)-(p+1);
for(int i=1;i<=n;++i) add(ef(line[i].l),ef(line[i].r),1,line[i].r-line[i].l);
for(int i=1;i<tot;++i) add(i,i+1,k,0);
S=tot+1; T=S+1;
add(S,1,k,0); add(tot,T,k,0);
printf("%d",MCMF());
return 0;
}
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=200+10,maxm=20000+10,INF=0x3f3f3f3f;
int n,m,k,C[maxn],F[maxn],S,T;
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow,w;
Node(){}
Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){flow=0;}
}node[2*maxm];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z,int w) {
node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
}
int from[maxn],zz[maxn],dis[maxn];
bool vis[maxn];
bool spfa() {
int s=1,t=0,x,y,z;
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(zz,0,sizeof(zz));
zz[++t]=S;dis[S]=0;vis[S]=1;
while(s<=t) {
x=zz[s%maxn];s++;vis[x]=0;
for(y=fir[x];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[z=node[y].y]<=dis[x]+node[y].w) continue;
dis[z]=dis[x]+node[y].w; from[z]=y;
if(!vis[z]) {
vis[z]=1;t++;
zz[t%maxn]=z;
}
}
}
return dis[T]!=INF;
}
int MCMF() {
int rs=0,now;
while(spfa()) {
now=INF;
for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
for(int i=T;i!=S;i=node[from[i]].x) {
node[from[i]].flow+=now;
node[from[i]^1].flow-=now;
rs+=node[from[i]].w*now;
}
}
return rs;
}
int main() {
n=read(); m=read(); k=read();
S=n+m+1;T=S+1; int x;
for(int i=1;i<=n;++i) {
add(S,i,k,0);
add(i,T,k-1,0);
}
for(int i=1;i<=m;++i) C[i]=read();
for(int i=1;i<=m;++i) F[i]=read();
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j)
add(n+i,T,1,(2*j-1)*C[i]-F[i]);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j) {
scanf("%1d",&x);
if(x) add(i,n+j,1,0);
}
printf("%d",MCMF());
return 0;
}
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1000+10,maxm=30*maxn,INF=0x3f3f3f3f;
int n,m,S,T,p[maxn];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow,w;
Node(){}
Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){flow=0;}
}node[2*maxm];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z,int w) {
node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
}
int from[maxn],zz[maxn],dis[maxn];
bool vis[maxn];
bool spfa() {
int s=1,t=0,x,y,z;
memset(dis,0x3f3f3f3f,sizeof(dis));
memset(zz,0,sizeof(zz));
zz[++t]=S;dis[S]=0;vis[S]=1;
while(s<=t) {
x=zz[s%maxn];s++;vis[x]=0;
for(y=fir[x];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[z=node[y].y]<=dis[x]+node[y].w) continue;
dis[z]=dis[x]+node[y].w; from[z]=y;
if(!vis[z]) {
vis[z]=1;t++;
zz[t%maxn]=z;
}
}
}
return dis[T]!=INF;
}
int MCMF() {
int rs=0,now;
while(spfa()) {
now=INF;
for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
for(int i=T;i!=S;i=node[from[i]].x) {
node[from[i]].flow+=now;
node[from[i]^1].flow-=now;
rs+=node[from[i]].w*now;
}
}
return rs;
}
int main() {
n=read(); m=read();
S=n+2;T=S+1;
for(int i=1;i<=n;++i) p[i]=read();
for(int i=1;i<=n+1;++i) {
if(p[i-1]-p[i]>0) add(S,i,p[i-1]-p[i],0);
else add(i,T,p[i]-p[i-1],0);
}
int l,r,c;
for(int i=1;i<=m;++i) {
l=read(); r=read(); c=read();
add(r+1,l,INF,c);
}
for(int i=1;i<=n;++i) add(i,i+1,INF,0);
printf("%d",MCMF());
return 0;
}
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=400+10,maxm=4*maxn,INF=0x3f3f3f3f;
int n,k,S,T,c[2*maxn];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y,cap,flow,w;
Node(){}
Node(int x,int y,int cap,int w):x(x),y(y),cap(cap),w(w){}
}node[2*maxm];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,int z,int w) {
node[++e]=Node(x,y,z,w); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0,-w);nxt[e]=fir[y];fir[y]=e;
}
int from[maxn],zz[maxn],dis[maxn];
bool vis[maxn];
bool spfa() {
int s=1,t=0,x,y,z;
memset(dis,-1,sizeof(dis));
memset(zz,0,sizeof(zz));
zz[++t]=S;dis[S]=0;vis[S]=1;
while(s<=t) {
x=zz[s%maxn];s++;vis[x]=0;
for(y=fir[x];y;y=nxt[y]) {
if(node[y].flow>=node[y].cap||dis[z=node[y].y]>=dis[x]+node[y].w) continue;
dis[z]=dis[x]+node[y].w; from[z]=y;
if(!vis[z]) {
vis[z]=1;t++;
zz[t%maxn]=z;
}
}
}
return dis[T]!=-1;
}
int MCMF() {
int rs=0,now;
while(spfa()) {
now=INF;
for(int i=T;i!=S;i=node[from[i]].x) now=min(now,node[from[i]].cap-node[from[i]].flow);
for(int i=T;i!=S;i=node[from[i]].x) {
node[from[i]].flow+=now;
node[from[i]^1].flow-=now;
rs+=node[from[i]].w*now;
}
}
return rs;
}
int main() {
n=read(); k=read();
S=2*n+2;T=S+1;
for(int i=1;i<=3*n;++i) c[i]=read();
for(int i=1;i<=n;++i) add(i,i+n,1,c[i+n]);
for(int i=1;i<2*n;++i) add(i,i+1,k,0);
for(int i=1;i<=n;++i) add(2*n+1,i,1,c[i]);
for(int i=n+1;i<=2*n;++i) add(i,T,1,c[i+n]);
add(S,2*n+1,k,0);
printf("%d",MCMF());
return 0;
}
题面有毒,汇点应该是n.
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const ll maxn=200+10,maxm=1000+10,INF=1e9;
ll n,m,S,T,ind[maxn];
ll ans;
ll aa;char cc;
ll read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
struct Node{
int x,y;ll cap,flow,w;
Node(){}
Node(int x,int y,ll cap,ll w):x(x),y(y),cap(cap),w(w){flow=0;}
}node[2*maxm];
int fir[maxn],nxt[2*maxm],e=1;
void add(int x,int y,ll z,ll w) {
// printf("add:%d -> %d cap:%lld w:%lld\n",x,y,z,w);
node[++e]=Node(x,y,z,w); nxt[e]=fir[x]; fir[x]=e;
node[++e]=Node(y,x,0,-w); nxt[e]=fir[y];fir[y]=e;
}
ll zz[maxn],dis[maxn],from[maxn];
bool vis[maxn];
bool spfa() {
for(int i=1;i<=n+2;++i) dis[i]=INF,from[i]=0;
int s=1,t=0,x,y,z,o;
dis[S]=0; zz[++t]=S;vis[S]=1;
while(s<=t) {
x=zz[s%maxn];s++; vis[x]=0;
for(y=fir[x];y;y=nxt[y]) {
z=node[y].y;
if(node[y].flow>=node[y].cap||dis[z]<=dis[x]+node[y].w) continue;
dis[z]=dis[x]+node[y].w;
from[z]=y;
if(!vis[z]) {
vis[z]=1; t++;
zz[t%maxn]=z;
}
}
}
return dis[T]<INF;
}
ll MCMF() {
ll rs=0,now;
while(spfa()) {
now=INF;
for(int x=T;x!=S;x=node[from[x]].x) now=min(now,node[from[x]].cap-node[from[x]].flow);
for(int x=T;x!=S;x=node[from[x]].x) {
rs+=now*node[from[x]].w;
node[from[x]].flow+=now;
node[from[x]^1].flow-=now;
}
}
return rs;
}
int main() {
n=read(); m=read();
int x,y,f,c; S=n+1;T=n+2;
for(int i=1;i<=m;++i) {
x=read(); y=read(); c=read(); f=read();
ind[y]+=f; ind[x]-=f;
if(f<=c) {
add(y,x,f,1);
if(f!=c) add(x,y,c-f,1);
add(x,y,INF,2);
}
else {
ans+=f-c;
add(y,x,f-c,0);
add(y,x,c,1);
add(x,y,INF,2);
}
}
for(int i=1;i<=n;++i) {
if(ind[i]<0) add(i,T,-ind[i],0);
else if(ind[i]>0) add(S,i,ind[i],0);
}
add(n,1,INF,0);
ans+=MCMF();
printf("%lld",ans);
return 0;
}
数据第4、5个点有毒。
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=2e4+10,INF=0x3f3f3f3f;
int n,m,S,T,ans;
char c[57][57];
int aa;char cc;
int read() {
aa=0;cc=getchar();
while(cc<'0'||cc>'9') cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
return aa;
}
int is_ok(char x) {
if(x=='.') return 0;
if(x>='0'&&x<='9') return x-'0';
if(x=='A'||x=='V'||x=='<'||x=='>') return -1;
return -2;
}
struct Node{
int x,y,cap,flow;
Node(){}
Node(int x,int y,int cap):x(x),y(y),cap(cap){flow=0;}
}node[6*maxn];
int cur[maxn],fir[maxn],nxt[6*maxn],e=1;
void add(int x,int y,int z) {
// printf("add:%d -> %d cap:%d\n",x,y,z);
node[++e]=Node(x,y,z); nxt[e]=fir[x];fir[x]=e;
node[++e]=Node(y,x,0); nxt[e]=fir[y];fir[y]=e;
}
int get_id(int x,int y,int p) {
return (x-1)*m+y+p*n*m;
}
void init() {
int xx,yy,dx,dy,nowmax,num,p;
for(int i=0;i<=n+1;++i) c[i][0]=c[i][m+1]='#';
for(int i=0;i<=m+1;++i) c[0][i]=c[n+1][i]='#';
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(is_ok(c[i][j])==-1){
switch(c[i][j]) {
case 'A':dx=-1;dy=0;p=1;break;
case 'V':dx=1;dy=0; p=1;break;
case '<':dx=0;dy=-1;p=0;break;
case '>':dx=0;dy=1; p=0;break;
}
xx=i+dx; yy=j+dy;
nowmax=0;
while((num=is_ok(c[xx][yy]))>=0) {
if(num>nowmax) nowmax=num;
xx+=dx; yy+=dy;
}
if(!nowmax) continue; ans+=nowmax;
xx=i; yy=j; num=0;
do{
if(!p) add(get_id(xx,yy,0),get_id(xx+dx,yy+dy,0),nowmax-num);
else add(get_id(xx+dx,yy+dy,1),get_id(xx,yy,1),nowmax-num);
xx+=dx; yy+=dy;
}while((num=is_ok(c[xx][yy]))!=nowmax);
if(!p) add(S,get_id(i,j,0),INF);
else add(get_id(i,j,1),T,INF);
}
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);
}
int dis[maxn],zz[maxn];
bool BFS() {
memset(dis,-1,sizeof(dis));
int s=1,t=0,x,y,z;
zz[++t]=S; dis[S]=1;
while(s<=t) {
x=zz[s++];
for(y=fir[x];y;y=nxt[y]) {
if(dis[z=node[y].y]!=-1||node[y].flow>=node[y].cap) continue;
dis[z]=dis[x]+1;
zz[++t]=z;
}
}
return dis[T]!=-1;
}
int DFS(int pos,int maxf) {
if(pos==T||!maxf) return maxf;
int rs=0,now,z;
for(int &y=cur[pos];y&&maxf;y=nxt[y]) {
if(dis[z=node[y].y]!=dis[pos]+1||node[y].flow>=node[y].cap) continue;
now=DFS(z,min(maxf,node[y].cap-node[y].flow));
node[y].flow+=now; node[y^1].flow-=now;
rs+=now;maxf-=now;
}
if(!rs) dis[pos]=-1;
return rs;
}
int Dinic() {
int rs=0;
while(BFS()) {
memcpy(cur,fir,sizeof(fir));
rs+=DFS(S,INF);
}
return rs;
}
int main() {
freopen("archery.in","r",stdin);
freopen("archery.out","w",stdout);
n=read(); m=read();
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);
S=2*n*m+1; T=S+1;
init();
ans-=Dinic();
printf("%d\n",ans);
return 0;
}