ZOJ 3229 Shoot the Bullet-上下界网络流
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 365
#define MAXM 1000
#define MAXC 100
#define MAXE (MAXN*2+MAXN*MAXC+MAXM*2+10)
#define INF 2000000000
struct node{
int v,c,b;
node *next,*back;
}edge[MAXE*2+10],*adj[MAXN+MAXM+10],*ecnt=&edge[0];
int n,m,C[MAXN+10],ans[MAXN+10][MAXC+10],s,t,ss,tt,S,T;
int tot,flow,du[MAXN+MAXM+10],d[MAXN+MAXM+10],vd[MAXN+MAXM+10],col[MAXN+10][MAXC+10];
int e[MAXN+10][MAXC+10],cnte;
void Init()
{
tot=cnte=0;
memset(adj,0,sizeof adj);
ecnt=&edge[0];
memset(du,0,sizeof du);
memset(col,0,sizeof col);
memset(e,0,sizeof e);
}
void addedge(int u,int v,int c,int b)
{
node *p=++ecnt; ++cnte;
p->v=v;
p->c=c,p->b=b;
p->next=adj[u],p->back=ecnt+1;
adj[u]=p;
p=++ecnt; ++cnte;
p->v=u;
p->c=0,p->b=b;
p->next=adj[v],p->back=ecnt-1;
adj[v]=p;
}
void limitflow(int x,int y,int b,int c)
{
addedge(x,y,c-b,b);
du[x]-=b,du[y]+=b;
}
void read()
{
int x,d,l,r;
s=1,t=n+m+2;
for(int i=1;i<=m;i++){
scanf("%d",&x);
limitflow(1+n+i,t,x,INF);
}
for(int i=1;i<=n;i++){
scanf("%d%d",&C[i],&d);
limitflow(s,1+i,0,d);
for(int j=1;j<=C[i];j++){
scanf("%d%d%d",&x,&l,&r);
e[i][j]=l;
limitflow(1+i,1+n+x+1,l,r);
col[i][j]=cnte;
}
}
limitflow(t,s,0,INF);
ss=t+1,tt=t+2;
for(int i=s;i<=t;i++){
if(du[i]>0) addedge(ss,i,du[i],0),tot+=du[i];
if(du[i]<0) addedge(i,tt,-du[i],0);
}
}
int aug(int u,int augc)
{
int augco=augc,mind=tt,delta,v; //tt,not T
if(u==T)
return augc;
for(node *p=adj[u];p;p=p->next){
v=p->v;
if(p->c>0){
if(d[u]==d[v]+1){
delta=aug(v,min(augco,p->c));
p->c-=delta;
p->back->c+=delta;
augco-=delta;
if(d[S]>=tt) //tt,not T
return augc-augco;
if(!augco)
break;
}
mind=min(mind,d[v]);
}
}
if(augco==augc){
vd[d[u]]--;
if(!vd[d[u]])
d[S]=tt+1; //tt,not T
d[u]=mind+1;
vd[d[u]]++;
}
return augc-augco;
}
void Isap(int s0,int t0)
{
S=s0,T=t0;
flow=0;
memset(d,0,sizeof d);
memset(vd,0,sizeof vd);
vd[0]=tt; // tt,not T,有反向边,点都还是连通的
while(d[S]<tt) //tt not T
flow+=aug(S,INF);
}
int main()
{
while(scanf("%d%d",&n,&m)==2){
Init();
read();
Isap(ss,tt);
if(flow==tot){
Isap(s,t);
printf("%d\n",flow);
memset(ans,0,sizeof ans);
/*for(int i=1;i<=n;i++){
for(node *p=adj[i+1];p;p=p->next){
if(p->v>=2+n&&p->v<=1+n+m)
ans[i][col[i][p->v-(n+1)]]=p->back->c+p->back->b;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=C[i];j++)
printf("%d\n",ans[i][j]);*/
for(int i=1;i<=n;i++)
for(int j=1;j<=C[i];j++)
printf("%d\n",e[i][j]+edge[col[i][j]].c);
}
else
printf("-1\n");
puts("");
}
}
但不知道为什么这个是错的:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 365
#define MAXM 1000
#define MAXC 100
#define MAXE (MAXN*2+MAXN*MAXC+MAXM*2+10)
#define INF 2000000000
struct node{
int v,c,b;
node *next,*back;
}edge[MAXE*2+10],*adj[MAXN+MAXM+10],*ecnt=&edge[0];
int n,m,C[MAXN+10],ans[MAXN+10][MAXC+10],s,t,ss,tt,S,T;
int tot,flow,du[MAXN+MAXM+10],d[MAXN+MAXM+10],vd[MAXN+MAXM+10],col[MAXN+10][MAXC+10];
void Init()
{
tot=0;
memset(adj,0,sizeof adj);
ecnt=&edge[0];
memset(du,0,sizeof du);
memset(col,0,sizeof col);
}
void addedge(int u,int v,int c,int b)
{
node *p=++ecnt;
p->v=v;
p->c=c,p->b=b;
p->next=adj[u],p->back=ecnt+1;
adj[u]=p;
p=++ecnt;
p->v=u;
p->c=0,p->b=b;
p->next=adj[v],p->back=ecnt-1;
adj[v]=p;
}
void limitflow(int x,int y,int b,int c)
{
addedge(x,y,c-b,b);
du[x]-=b,du[y]+=b;
}
void read()
{
int x,d,l,r;
s=1,t=n+m+2;
for(int i=1;i<=m;i++){
scanf("%d",&x);
limitflow(1+n+i,t,x,INF);
}
for(int i=1;i<=n;i++){
scanf("%d%d",&C[i],&d);
limitflow(s,1+i,0,d);
for(int j=1;j<=C[i];j++){
scanf("%d%d%d",&x,&l,&r);
col[i][x+1]=j;
limitflow(1+i,1+n+x+1,l,r);
}
}
limitflow(t,s,0,INF);
ss=t+1,tt=t+2;
for(int i=s;i<=t;i++){
if(du[i]>0) addedge(ss,i,du[i],0),tot+=du[i];
if(du[i]<0) addedge(i,tt,-du[i],0);
}
}
int aug(int u,int augc)
{
int augco=augc,mind=tt,delta,v;
if(u==T)
return augc;
for(node *p=adj[u];p;p=p->next){
v=p->v;
if(p->c>0){
if(d[u]==d[v]+1){
delta=aug(v,min(augco,p->c));
p->c-=delta;
p->back->c+=delta;
augco-=delta;
if(d[S]>=tt)
return augc-augco;
if(!augco)
break;
}
mind=min(mind,d[v]);
}
}
if(augco==augc){
vd[d[u]]--;
if(!vd[d[u]])
d[S]=tt+1;
d[u]=mind+1;
vd[d[u]]++;
}
return augc-augco;
}
void Isap(int s0,int t0)
{
S=s0,T=t0;
flow=0;
memset(d,0,sizeof d);
memset(vd,0,sizeof vd);
vd[0]=tt;
while(d[S]<tt)
flow+=aug(S,INF);
}
int main()
{
while(scanf("%d%d",&n,&m)==2){
Init();
read();
Isap(ss,tt);
if(flow==tot){
Isap(s,t);
printf("%d\n",flow);
memset(ans,0,sizeof ans);
for(int i=1;i<=n;i++){
for(node *p=adj[i+1];p;p=p->next){
if(p->v>=1+n&&p->v<=1+n+m)
ans[i][col[i][p->v-(n+1)]]=p->back->c+p->back->b;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=C[i];j++)
printf("%d\n",ans[i][j]);
}
else
printf("-1\n");
puts("");
}
}