bzoj1449: [JSOI2009]球队收益
类似于修车那道题的思维。拆点。手画一下比较容易出来。。。YY能力不可靠啊~~~
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define REP(i,s,t) for(int i=s;i<=t;i++) #define qwq(x) for(edge *o=head[x];o;o=o->next) #define op() clr(head,0);pt=edges; int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=6005; const int maxn=2000000; const int inf=0x7f7f7f7f; struct edge{ int to,cap,cost;edge *next,*rev; }; edge edges[maxn],*pt,*head[nmax],*p[nmax]; int d[nmax],a[nmax],c[nmax],dd[nmax],win[nmax],lose[nmax],cnt[nmax]; bool inq[nmax]; void add(int u,int v,int d,int w){ pt->to=v;pt->cap=d;pt->cost=w;pt->next=head[u];head[u]=pt++; } void adde(int u,int v,int d,int w){ add(u,v,d,w);add(v,u,0,-w);head[u]->rev=head[v];head[v]->rev=head[u]; } int mincost(int s,int t){ int cost=0; while(1){ clr(d,0x7f);clr(inq,0);inq[s]=1;d[s]=0;a[s]=inf; queue<int>q;q.push(s); while(!q.empty()){ int x=q.front();q.pop();inq[x]=0; qwq(x) if(o->cap>0&&d[o->to]>d[x]+o->cost){ int to=o->to;d[to]=d[x]+o->cost; a[to]=min(a[x],o->cap);p[to]=o; if(!inq[to]) q.push(to),inq[to]=1; } } if(d[t]==inf) break; cost+=d[t]*a[t]; int x=t; while(x!=s) p[x]->cap-=a[t],p[x]->rev->cap+=a[t],x=p[x]->rev->to; } return cost; } int main(){ int n=read(),m=read(),u,v,s=0,t=n+m+1; op();clr(cnt,0);int ans=0; rep(i,n) win[i]=read(),lose[i]=read(),c[i]=read(),dd[i]=read(); rep(i,m) u=read(),v=read(),cnt[u]++,cnt[v]++,adde(s,i,1,0),adde(i,u+m,1,0),adde(i,v+m,1,0); rep(i,n){ lose[i]+=cnt[i]; ans+=c[i]*win[i]*win[i]+dd[i]*lose[i]*lose[i]; rep(j,cnt[i]){ adde(i+m,t,1,2*(c[i]*win[i]-dd[i]*lose[i])+c[i]+dd[i]); win[i]++;lose[i]--; } } /*REP(i,0,n+m+1){ qwq(i) printf("%d ",o->to);printf("\n"); }*/ printf("%d\n",ans+mincost(s,t)); return 0; }
1449: [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 702 Solved: 403
[Submit][Status][Discuss]
Description
Input
Output
一个整数表示联盟里所有球队收益之和的最小值。
Sample Input
3 3
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
Sample Output
43