BZOJ 4873: [Shoi2017] sushi restaurant is closed maximum weight subgraph

title

BZOJ 4873
LUOGU 3749
Description

Kiana like recently went to a very delicious sushi restaurant. Every night, this restaurant will provide order n kinds of sushi, sushi i-th symbol ai and have a delicious degree di, i, different kinds of sushi is possible to use the same code. Copies of each sushi are unlimited, Kiana also get unlimited eat sushi, but the sushi you can only take one each, and each must be removed sushi sushi restaurant by a continuous sequence of period , i.e. Kiana removed at once each of a first and second kind of sushi, can be removed once a second and third of each kind of sushi, but not once removed first and the third kind of sushi. Because of the kind of sushi restaurant offers a range of different types of sushi and have an impact on each other: eating sushi with salmon and squid sushi might be great, but eat sushi and fruit may be stomach pain. Therefore, Kiana defined a comprehensive deliciousness di, j (i <j), said in a sushi taken in, if you include all the sushi from the i-th to the j part of the restaurant provided, eat the take after all of the extra delicious sushi available. Because of sushi take take some time, so we think will not affect each other twice to fetch between sushi. Note that when eating sushi once taken, more than one degree will be integrated delicious accumulate, such as if Kiana once took away 1,2,3 kinds of sushi each, in addition to d1,3, d1,2, d2,3 It will be accumulated into the total degree of delicacy. Amazingly, gourmet criteria Kiana there is a memory, either of a single delicious sushi, or sushi, a variety of delicious combination of comprehensive, included in the total deliciousness of Kiana will only be accumulated once . For example, if a Kiana removed once the first and second kinds of sushi each, and once removed a second and third kinds of sushi each, then a total of these two delicious sushi taken degree d1,1 + d2 , 2 + d3,3 + d1,2 + d2,3, d2,2 wherein counted only once. Curiously, this sushi restaurant charges very unusual. Specifically, if the total Kiana eaten c (c> 0), code-named species sushi x, then she needs to pay mx ^ 2 + cx dollars for these sushi restaurant where m is a constant given. The maximum total amount of money now Kiana want to know, eat sushi in this restaurant, you can get a taste of the total (including all deliciousness single sushi eaten and all accumulated comprehensive deliciousness) minus cost of how many. Because she does not count, so you want to tell her the

Input

The first line contains two positive integers n, m, respectively, the total number of constants which sushi restaurant offers and price calculation used in sushi.
The second line contains n a positive integer, wherein the number of k is the k ak sushi code parts.
Next row n, the i-th row comprising n-i + 1 integer, wherein the number of the j-di, i + j-1 represents the sushi can eat
respective deliciousness obtained, see the description of the problem specific meaning.
N <= 100, Ai <= 1000

Output

The output common line contains a positive integer representing the maximum number of total deliciousness Kiana total money that can be obtained by subtracting the cost of.

Sample Input

3 1
2 3 2
5 -10 15
-10 15
15

Sample Output

12
[Sample 1] described
in this set of samples, a total of three parts restaurant offers sushi, followed by their code a1 = 2, a2 = 3, a3 = 2, the constant m = 1 when calculating the price. In every assurance
at times take sushi can get a new degree of delicious premise, Kiana, a total of 14 different sushi options:

  1. Kiana a do not eat sushi, so the total money spent and total deliciousness get her number is 0, the two subtraction is 0;
  2. Kiana sushi just take 1, take the first and only one sushi, i.e. where she is taken sushi {[1, 1]}, thus obtained total deliciousness is 5, the total amount of money spent
    to 2 ^ 1-2 * 2 + 1 = 6, both the subtraction is -1;
  3. Kiana just take sushi 1, and only the second sushi taken, i.e., where she is taken sushi {[2,2]}, thus obtained total deliciousness -10, the total amount of money spent for the ^ 1-3 3 * 2 + 1 = 12, both a subtraction of -22;
  4. Kiana sushi just take 1, take the first three and only sushi, i.e. where she is taken sushi {[3,3]}, total deliciousness thus obtained was 15, the total amount of money spent for a 2 + 2 ^ . 1 2 = 6, 9 subtract the two;
  5. Kiana sushi just take 1, 2, and take the first sushi, i.e. where she is taken sushi {[1,2]}, thus obtained total deliciousness is 5 + (- 10) + (- 10) = -15, the total amount of money spent for the (2 ^ 1-2 * 2 + 1) + (2 ^ 1-3 * 3 + 1) = 18, -33 subtracting the two;
  6. Kiana sushi just take 1, 2, 3 and takes a sushi, i.e. where she is taken sushi {[2,3]}, thus obtained total deliciousness is (-10) + 15 + 15 = 20, cost the total amount of money of (2 ^ 1-2 * 2 + 1) + (1 * 3 + 1 * 2 ^ 3) = 18, a subtraction of both 2;
  7. Kiana sushi just take 1, 2, 3 and takes a sushi, i.e. where she is taken sushi {[1,3]}, thus obtained total deliciousness is 5 + (- 10) +15+ ( -10) + 15 + 15 = 30, the total amount of money spent for the (1 + 2 * 2 * 2 ^ 2) + (1 * 3 + 1 * 2 ^ 3) = 20, 10 subtract the two.
  8. Kiana sushi was twice, first take the first one sushi, the second take the first 2 sushi, i.e. where she is taken sushi {[1,1], [2,2]}, thus obtained total delicious It is 5 + (- 10) = - 5, the total amount of money spent for the (1 + 2 * 1 * 2 ^ 2) + (1 * 3 + 1 * 2 ^ 3) = 18, a subtraction of the two - twenty three;
  9. Kiana sushi was twice, first take the first one sushi, take the first three second sushi, i.e. where she is taken sushi {[1,1], [3,3]}, thus obtained total delicious is 5 + 15 = 20, total amount of money spent is 1 2 2 + 2 ^ 2 = 8, 12 subtract the two;
  10. Kiana sushi was twice, first take the first 2 sushi, take the first three second sushi, i.e. where she is taken sushi {[2,2], [3,3]}, thus obtained total delicious degrees (-10) = 5 + 15, total amount of money spent for the (1 + 2 * 1 * 2 ^ 2) + (1 * 3 + 1 * 2 ^ 3) = 18, two subtraction -13 ;
  11. Kiana sushi was twice, the first time to take the first and second sushi, take the first three second sushi, i.e. where she is taken sushi {[1,2], [3,3]}, thus obtained the total taste is 5 + (- 10) + (- 10) + 15 = 0, total amount of money spent (1 * 2 ^ 2 + 2 * 2) + (1 * 3 ^ 2 + 1 * 3) = 20, both a subtraction of -20;
  12. Kiana sushi was twice, first take the first one sushi, take the first 2,3 second of sushi, i.e. where she is taken sushi {[1,1], [2,3]}, thus obtained the total deliciousness 5 + (- 10) + 15 + 15 = 25, total amount of money is spent (1-22 + 2-2) + (1-32 + 1-3) = 20, a subtraction of the two 5;
  13. Kiana sushi was twice, first take sushi 1,2, 2,3 of the second take sushi, i.e. where she is taken sushi {[1,2], [2,3]}, so total taste of the obtained 5 + (- 10) + 15 + (- 10) + 15 = 15, the total amount of money spent for the (1 + 2 * 2 * 2 ^ 2) + (1 * 3 ^ 2 + 1 * 3) = 20, subtract the two -5;
  14. Kiana sushi taken three times, first take the first one sushi, the second take the first 2 sushi, take the first three third sushi, i.e. where she is taken sushi {[1, 1], [2, 2], [3,3]}, thus obtained total deliciousness is 5 + (- 10) + 15 = 10, the total amount of money spent for the (1 + 2 * 2 * 2 ^ 2) + (1 * 3 ^ 2 * 3 + 1) = 20, two subtraction
    -10.
    So the value of the total amount of money spent by subtracting the total of delicious options will Kiana 9, when she received a maximum of 12.

Source

Black Kat Liaoning and Shanghai six provinces of Shanxi and Hebei exam

analysis

Really take a language ah! Face such a long title. (▼ dish ▼ #)

according to

You can get the total deliciousness (including delicious sushi for all single and eaten all the accumulated comprehensive deliciousness) minus the maximum total number of how much money is spent

This question can be drawn closed model is the maximum weight subgraph (a little image of the ah, I understand, there are positive points right, negative right point, the final answer is a difference, the amount, it seems only right to maximum closure subgraph is such a thing).

Figure routine so you can build a wave, but there is still quite good thinking:

  1. For all \ ((i, j) \ ) proceeds, each of which will be seen as a point, if the weight value \ (C \) is positive, from \ (source S \) connected over capacity \ (C \ ) , if the weight is negative, it is connected to the \ (T sink \) to a capacity of \ (- C \) ;
  2. For all \ ((i, j) \ ) income, to include the interval \ (i \) to \ (j \) No. sushi even side, capacity \ (INF \) , indicate that you must choose the corresponding sushi to choose this interval;
  3. For all sushi type \ (A [I] \) , to open a point of their respective to (t sink \) \ connected side capacity of \ (m * A [I] * A [I] \) ;
  4. For \ (1 \ sim n \) each of sushi, the type to which they belong \ (a [i] \) connected edge capacity \ (INF \) ; the \ (sink T \) connected edge capacity \ (C [I] \) ;
  5. For all \ ((I, J) \) , the \ ((i + 1, j ) \) and \ ((i, j-1 ) \) connected edge capacity \ (INF \) , represents a group selected a large range certainly have to choose between a large range of cells included;
  6. With total revenue minus the minimum cut can be.

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10,maxm=1e6+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; 
}

template<typename T>inline void write(T x)
{
    if (!x) { putchar('0'); return ; }
    if (x<0) putchar('-'), x=-x;
    T num=0, ch[20];
    while (x) ch[++num]=x%10+48, x/=10;
    while (num) putchar(ch[num--]);
}

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

int s,t;
int dist[maxn];
inline bool bfs()
{
    queue<int>q;
    memset(dist,0,sizeof(dist));
    q.push(s);dist[s]=1;
    while (!q.empty())
    {
        int x=q.front();
        q.pop();
        for (int i=head[x]; i; i=Next[i])
        {
            int y=ver[i];
            if (edge[i] && !dist[y])
            {
                dist[y]=dist[x]+1;
                if (y==t) return 1;
                q.push(y);
            }
        }
    }
    return 0;
}

inline int get(int x,int low)
{
    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]+1)
        {
            int a=get(y,min(tmp,edge[i]));
            if (!a) dist[y]=0;
            edge[i]-=a;
            edge[i^1]+=a;
            if (!(tmp-=a)) break;
        }
    }
    return low-tmp;
}

int a[101],c[101][101],pos[1010],id[101][101];
ll sum;
bool vis[1010];
int main()
{
    int n,m;read(n);read(m);
    for (int i=1; i<=n; ++i) read(a[i]);
    for (int i=1; i<=n; ++i)
        for (int j=i; j<=n; ++j) read(c[i][j]);

    int tot=0;
    for (int i=1; i<=n; ++i)
        for (int j=i; j<=n; ++j) id[i][j]=++tot;
    for (int i=1; i<=n; ++i)
        if (!vis[a[i]]) vis[a[i]]=1,pos[a[i]]=++tot;//给每种寿司代号编号
    s=0,t=tot+n+1;
    memset(vis,0,sizeof(vis));
    for (int i=1; i<=n; ++i)
        if (!vis[a[i]]) vis[a[i]]=1,add(pos[a[i]],t,m*a[i]*a[i]);
    for (int i=1; i<=n; ++i) add(i+tot,pos[a[i]],inf),add(i+tot,t,a[i]);//种类
    for (int i=1; i<=n; ++i)
        for (int j=i; j<=n; ++j)
        {
            if (c[i][j]>0)
            {
                sum+=c[i][j];
                add(s,id[i][j],c[i][j]);//点权为正,连向源点
                add(id[i][j],i+tot,inf);
                add(id[i][j],j+tot,inf);//同下
            }
            else if (c[i][j]<0)
            {
                add(id[i][j],t,-c[i][j]);//点权为负,连向汇点
                add(id[i][j],i+tot,inf);
                add(id[i][j],j+tot,inf);//选了这个区间,这两个点就必须选
            }
            if (i!=j) add(id[i][j],id[i][j-1],inf),add(id[i][j],id[i+1][j],inf);//[l,r]->[l,r-1],[l,r]->[l+1,r]
        }
    int ans=0;
    while (bfs()) ans+=get(s,inf);
    write(sum-ans);
    return 0;
}

Guess you like

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