BZOJ 1449: [JSOI2009] team returns the minimum cost maximum flow

title

\(~\)
BZOJ 1449
LUOGU 4307
Description

In a basketball league, there \ (n \) teams, teams of expenditure is the outcome of screening and their relationship, specifically, the \ (i \) of the total expenditure of the season teams are \ (C_i \ X ^ 2 + D_i Times \ Y ^ 2 Times, D_i \ Le C_i \) . (To win more prize money to players on multi-Well) where \ (x, y \) represent the only team this season, the outcome of screening. Now the season reached the half, each team were made \ (a_i \) wins and \ (b_i \) defeat. And then there \ (m \) matches to be. The minimum total expenditures league teams ask is how much.

Input

The first row \ (n, m \)
Next \ (n-\) lines each \ (4 \) integer \ (a_i, b_i, C_i,
D_i \) then the next \ (m \) lines each two integers \ (s \) , \ (t \) denotes \ (s \) there will be a match between the teams and tt teams, attention may be multiple games between the two teams.

Output

An integer that represents the minimum value of all the teams in the league and Revenue.

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

对于20%的数据\ (2 \ k \ a 10.0 \ the m \ 20 \) ;
对于100%的数据\ (2 \ k \ the 5000.0 \ the m \ the 1000.0 \ the D_i \ the C_i \ the 10.0 \ the a_i, b_i \ 50 \) .

analysis

  • Assuming that every game the two teams are negative, calculates the initial return;
  • Consider each game, one team wins;
    • From \ (source S \) to \ (I game \) connected capacity side 1, the cost of 0;
    • Then consider the incremental cost: income more than win a game generated. That \ ((C * (w + 1) ^ 2 + D * (l-1) ^ 2) - (C * w ^ 2 + D * l ^ 2) = 2w * C-2l * D + C + D \) .
      • For a team, after assuming \ (M \) field which participate \ (X \) field, then the initial \ (W = win, lose L = X + \) , after each win a \ (w ++, l - ~ - \) .
      • We from \ (team \) to (t sink \) \ Even \ (X \) edges, which represent won \ (J \) relative to win the game when the \ (j-1 \) field when income increments.
      • Due increments, so we can guarantee the correctness.
  • \ (ans = \) all the teams initial gains \ (+ \) the minimum cost maximum flow costs.
  • The range of the array to consider carefully, otherwise reap unexpected results of the evaluation.

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=5010,maxm=6010,maxe=1e5+10,inf=0x3f3f3f3f;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
    x=0;
    T f=1, ch=getchar();
    while (!isdigit(ch) && ch^'-') ch=getchar();
    if (ch=='-') f=-1, ch=getchar();
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}

char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x)
{
    if (!x) *fe++=48;
    if (x<0) *fe++='-', x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) *fe++=ch[num--];
    *fe++='\n';
}

int ver[maxe],edge[maxe],Next[maxe],cost[maxe],head[maxm],len=1;
inline void add(int x,int y,int z,int c)
{
    ver[++len]=y,edge[len]=z,cost[len]=c,Next[len]=head[x],head[x]=len;
    ver[++len]=x,edge[len]=0,cost[len]=-c,Next[len]=head[y],head[y]=len;
}

int s,t;
int dist[maxm];
bool vis[maxm];
inline bool spfa()
{
    memset(dist,0x3f,sizeof(dist));
    memset(vis,0,sizeof(vis));
    queue<int>q;q.push(s);
    dist[s]=0,vis[s]=1;
    while (!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for (int i=head[x]; i; i=Next[i])
        {
            if (!edge[i]) continue;
            int y=ver[i];
            if (dist[y]>dist[x]+cost[i])
            {
                dist[y]=dist[x]+cost[i];
                if (!vis[y]) q.push(y),vis[y]=1;
            }
        }
    }
    if (dist[t]==inf) return false;
    else return true;
}

int ans;
inline int get(int x,int low)
{
    vis[x]=1;
    if (x==t) return low;
    int tmp=low;
    for (int i=head[x]; i; i=Next[i])
    {
        int y=ver[i];
        if (edge[i] && dist[y]==dist[x]+cost[i] && (!vis[y] || y==t))
        {
            int a=get(y,min(tmp,edge[i]));
            if (a>0)
            {
                ans+=a*cost[i];
                edge[i]-=a;
                edge[i^1]+=a;
                if (!(tmp-=a)) break;
            }
        }
    }
    return low-tmp;
}

inline void NetFlow()
{
    while (spfa())
    {
        vis[t]=1;
        while (vis[t])
        {
            memset(vis,0,sizeof(vis));
            get(s,inf);
        }
    }
}

typedef int iarr[maxn];
iarr win,lose,c,d,In;
int main()
{
    int n,m;read(n);read(m);
    s=0,t=n+m+1;
    for (int i=1; i<=n; ++i) read(win[i]),read(lose[i]),read(c[i]),read(d[i]);
    for (int i=1,x,y; i<=m; ++i) add(s,i,1,0),read(x),read(y),add(i,x+m,1,0),add(i,y+m,1,0),++In[x],++In[y];
    for (int i=1; i<=n; ++i) lose[i]+=In[i];
    for (int i=1; i<=n; ++i) ans+=win[i]*win[i]*c[i]+lose[i]*lose[i]*d[i];//直接计算初始收益
    for (int i=1; i<=n; ++i)
        for (int j=1; j<=In[i]; ++j) add(i+m,t,1,2*c[i]*win[i]+c[i]+d[i]-2*d[i]*lose[i]),--lose[i],++win[i];
    NetFlow();
    write(ans);
    flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11318051.html