bzoj3876: [Ahoi2014&Jsoi2014]支线剧情
我真是看题之神zzzzzzz,在任意时刻都可以直接回起点啊
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; const int _=1e2; const int maxn=300+10; const int maxe=5*1e3+_; const int inf=(1<<28); struct node { int x,y,c,d,next; }a[2*(maxe+3*maxn)];int len,last[maxn]; void ins(int x,int y,int c,int d) { // printf("%d %d %d %d\n",x,y,c,d); len++; a[len].x=x;a[len].y=y;a[len].c=c;a[len].d=d; a[len].next=last[x];last[x]=len; len++; a[len].x=y;a[len].y=x;a[len].c=0;a[len].d=-d; a[len].next=last[y];last[y]=len; } int st,ed; int pre[maxn],c[maxn],d[maxn],ans; int list[maxn];bool v[maxn]; bool spfa() { memset(d,63,sizeof(d));d[st]=0;c[st]=(1<<30); memset(v,false,sizeof(v));v[st]=true; int head=1,tail=2;list[1]=st; while(head!=tail) { int x=list[head]; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(a[k].c>0&&d[y]>d[x]+a[k].d) { d[y]=d[x]+a[k].d; c[y]=min(a[k].c,c[x]); pre[y]=k; if(v[y]==false) { v[y]=true; list[tail]=y; tail++;if(tail==maxn)tail=1; } } } v[x]=false; head++;if(head==maxn)head=1; } if(d[ed]==d[0])return false; else { int y=ed;ans+=c[ed]*d[ed]; while(y!=st) { int k=pre[y]; a[k].c-=c[ed]; a[k^1].c+=c[ed]; y=a[k].x; } return true; } } int u[maxn]; int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n,m,x,dd; scanf("%d",&n);n++; st=n+1,ed=n+2; ans=0; len=1; for(int i=1;i<n;i++) { scanf("%d",&m); for(int j=1;j<=m;j++) { scanf("%d%d",&x,&dd); ins(i,x,inf,dd),u[i]--,u[x]++; ans+=dd; } ins(i,n,inf,0); } ins(n,1,inf,0); for(int i=1;i<=n;i++) if(u[i]<0)ins(i,ed,-u[i],0); else if(u[i]>0)ins(st,i,u[i],0); while(spfa()); printf("%d\n",ans); return 0; }
pain and happy in the cruel world.