您的位置:首页 > Web前端 > JavaScript

1449: [JSOI2009]球队收益

2017-01-08 09:33 309 查看

1449: [JSOI2009]球队收益

Time Limit: 5 Sec Memory Limit: 64 MB
Submit: 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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: