1449: [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 937 Solved: 541
[ Submit][ Status][ Discuss]
Description
![](http://www.lydsy.com/JudgeOnline/images/1449_1.jpg)
Input
![](http://www.lydsy.com/JudgeOnline/images/1449_2.jpg)
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
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
inline void print(int x)
{if(x<0)putchar('-');if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=10100,inf=0X3f3f3f3f;
int n,m,c[N],d[N],win[N],lose[N],S,T=N-1;
int ecnt=1,last[N];
struct EDGE{int to,nt,val,ct;}e[N<<4];
inline void readd(int u,int v,int val,int ct)
{e[++ecnt]=(EDGE){v,last[u],val,ct};last[u]=ecnt;}
inline void add(int u,int v,int val,int ct)
{readd(u,v,val,ct);readd(v,u,0,-ct);}
int dis[N],q[N];
bool inq[N],vis[N];
bool spfa()
{
memset(dis,0X3f,sizeof(dis));memset(vis,0,sizeof(vis));
int head=0,tail=1;q[0]=S;dis[S]=0;
while(head<tail)
{
int u=q[head++];head%=N;inq[u]=0;
for(int i=last[u];i;i=e[i].nt)
if(e[i].val&&dis[e[i].to]>dis[u]+e[i].ct)
{
dis[e[i].to]=dis[u]+e[i].ct;
if(!inq[e[i].to])q[tail++]=e[i].to,tail%=N,inq[e[i].to]=1;
}
}
return dis[T]^inf;
}
int ans=0;
int dfs(int u,int lim)
{
if(!lim||u==T){ans+=dis[u]*lim;return lim;}
int res=0;vis[u]=1;
for(int i=last[u];i;i=e[i].nt)
if(e[i].val&&!vis[e[i].to]&&dis[e[i].to]==dis[u]+e[i].ct)
{
int tmp=dfs(e[i].to,min(lim,e[i].val));
e[i].val-=tmp;e[i^1].val+=tmp;res+=tmp;lim-=tmp;
if(!lim)break;
}
if(!res)dis[u]=-1;
return res;
}
void mincf()
{while(spfa())dfs(S,inf);}
int ind[N];
int main()
{
n=read();m=read();
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();ind[x]++;ind[y]++;
add(i+n,x,1,0);add(i+n,y,1,0);add(S,i+n,1,0);
}
for(int i=1;i<=n;++i)
{
lose[i]+=ind[i];ans+=c[i]*win[i]*win[i]+d[i]*lose[i]*lose[i];
while(ind[i]>-1){add(i,T,1,2*c[i]*win[i]-2*d[i]*lose[i]+d[i]+c[i]);win[i]++;lose[i]--;ind[i]--;}
}
mincf();print(ans);puts("");return 0;
}
/*
3 3
1 0 2 1
1 1 10 1
0 1 3 3
1 2
2 3
3 1
43
*/