还是论文题
话说照我这个速度要刷到猴年马月(他喵的已经是猴年了QAQ)
这题模型挺好想得,很直观的最大费用最大流,唯一要想一下的就是优化了。
当然还有个很坑爹的地方就是spfa可以求2维费用流(两个关键字)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int inf=1e9; struct Edge{int from,to,next,v,c,c1;}e[200005]; int head[310],cnt; void ins(int u,int v,int w,int c,int c1){ e[++cnt]=(Edge){u,v,head[u],w,c,c1};head[u]=cnt; } void insert(int u,int v,int w,int c,int c1){ ins(u,v,w,c,c1);ins(v,u,0,-c,-c1); } int d[310],from[310],h[310]; bool inq[310]; bool spfa(int s,int t,int &cost,int &sum){ memset(d,-0x3f,sizeof(d)); memset(h,-0x3f,sizeof(h)); d[s]=0;h[s]=0;queue<int>q;q.push(s); while(!q.empty()){ int u=q.front();q.pop();inq[u]=0; for(int i=head[u];i;i=e[i].next) if(e[i].v&&(d[e[i].to]<d[u]+e[i].c||(d[e[i].to]==d[u]+e[i].c&&h[e[i].to]<h[u]+e[i].c1))){ d[e[i].to]=d[u]+e[i].c; h[e[i].to]=h[u]+e[i].c1; from[e[i].to]=i; if(!inq[e[i].to])inq[e[i].to]=1,q.push(e[i].to); } } if(d[t]<0)return false; int x=inf; for(int i=from[t];i;i=from[e[i].from])x=min(x,e[i].v); for(int i=from[t];i;i=from[e[i].from]) e[i].v-=x,e[i^1].v+=x; cost+=x*d[t];sum+=x*h[t]; return true; } int ans,sum; void mcf(int s,int t){while(spfa(s,t,ans,sum));} int A,B,C,a[100105],b[100105],c[100105],rk[100105]; bool cmpa(int i,int j){ if(a[i]==a[j])return a[i]+b[i]+c[i]>a[j]+b[j]+c[j]; return a[i]>a[j]; } bool cmpb(int i,int j){ if(b[i]==b[j])return a[i]+b[i]+c[i]>a[j]+b[j]+c[j]; return b[i]>b[j]; } bool cmpc(int i,int j){ if(c[i]==c[j])return a[i]+b[i]+c[i]>a[j]+b[j]+c[j]; return c[i]>c[j]; } int id[310]; int main(){ //freopen("a.in","r",stdin); int cas;scanf("%d",&cas); while(cas--){ int n;scanf("%d",&n); scanf("%d%d%d",&A,&B,&C); ans=sum=0; for(int i=1;i<=n;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]); for(int i=1;i<=n;i++)rk[i]=i; sort(rk+1,rk+1+n,cmpa); for(int i=1;i<=A+B+C;i++)id[i]=rk[i]; for(int i=1;i<=n;i++)rk[i]=i; sort(rk+1,rk+1+n,cmpb); for(int i=1;i<=A+B+C;i++)id[i+A+B+C]=rk[i]; for(int i=1;i<=n;i++)rk[i]=i; sort(rk+1,rk+1+n,cmpc); for(int i=1;i<=A+B+C;i++)id[i+2*(A+B+C)]=rk[i]; int m=3*(A+B+C); sort(id+1,id+1+m);m=unique(id+1,id+1+m)-id-1; memset(head,0,sizeof(head));cnt=1; int S=0,p1=m+1,p2=m+2,p3=m+3,T=m+4; insert(S,p1,A,0,0);insert(S,p2,B,0,0);insert(S,p3,C,0,0); for(int i=1;i<=m;i++){ insert(p1,i,1,a[id[i]],a[id[i]]+b[id[i]]+c[id[i]]); insert(p2,i,1,b[id[i]],a[id[i]]+b[id[i]]+c[id[i]]); insert(p3,i,1,c[id[i]],a[id[i]]+b[id[i]]+c[id[i]]); insert(i,T,1,0,0); } mcf(S,T); printf("%d %d\n",ans,sum); } return 0; }