1449: [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 757 Solved: 437
[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
HINT
Source
#include<cstdio> #include<cstring> #include<iostream> #define b(x) (x*x) #define IN inline using namespace std; IN int read(){ register int x=0,f=1; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int N=1e5+10; const int M=6010; const int inf=1e9; struct node{ int v,next,cap,cost; }e[N*10];int tot=1; int n,m,S,T,ans,head[M],dis[M],q[N*10]; int win[M],lose[M],C[M],D[M],rem[M]; bool vis[M]; IN void add(int x,int y,int cap,int cost){ e[++tot].v=y;e[tot].cap=cap;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].cap=0;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot; } IN bool spfa(){ for(int i=S;i<=T;i++) vis[i]=0,dis[i]=inf; int h=0,t=1;q[t]=T;dis[T]=0;vis[T]=1; while(h!=t){ int x=q[++h];vis[x]=0; for(int i=head[x];i;i=e[i].next){ int v=e[i].v; if(e[i^1].cap&&dis[v]>dis[x]+e[i^1].cost){ dis[v]=dis[x]+e[i^1].cost; if(!vis[v]){ vis[v]=1; q[++t]=v; } } } } return dis[S]<inf; } int dfs(int x,int f){ vis[x]=1; if(x==T) return f; int used=0,w; for(int i=head[x];i;i=e[i].next){ int v=e[i].v; if(!vis[v]&&e[i].cap&&dis[v]+e[i].cost==dis[x]){ w=dfs(v,min(f-used,e[i].cap)); e[i].cap-=w;e[i^1].cap+=w; ans+=w*e[i].cost; used+=w; if(used==f) return used; } } return used; } IN void zkw(){ while(spfa()){ vis[T]=1; while(vis[T]){ memset(vis,0,sizeof vis); dfs(S,inf); } } } int main(){ n=read();m=read();S=0;T=n+m+1; for(int i=1;i<=n;i++) win[i]=read(),lose[i]=read(),C[i]=read(),D[i]=read(); for(int i=1,x,y;i<=m;i++){ x=read();y=read();rem[x]++;rem[y]++; add(S,i,1,0); add(i,x+m,1,0); add(i,y+m,1,0); } for(int i=1;i<=n;i++) lose[i]+=rem[i]; for(int i=1;i<=n;i++) ans+=b(win[i])*C[i]+b(lose[i])*D[i]; for(int i=1;i<=n;i++){ for(int j=1;j<=rem[i];j++){ add(i+m,T,1,2*win[i]*C[i]-2*lose[i]*D[i]+C[i]+D[i]); win[i]++;lose[i]--; } } zkw(); printf("%d",ans); return 0; }