2938 寿司餐厅
题目详情见bzoj4873[Shoi2017]寿司餐厅,这里只放代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int mxn=30505;
int read(){
int x=0,f=1;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;
}
struct edge{
int u,v,nxt,f;
}e[mxn<<6];
int hd[mxn],mct=1;
inline void add_edge(int u,int v,int f){
e[++mct].v=v;e[mct].u=u;e[mct].nxt=hd[u];e[mct].f=f;hd[u]=mct;return;
}
void insert(int u,int v,int f){
add_edge(u,v,f); add_edge(v,u,0);
return;
}
int S,T;
int d[10085];
bool BFS(){
memset(d,0,sizeof d);
queue<int>q;
d[S]=1;
q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(!d[v] && e[i].f){
d[v]=d[u]+1;
q.push(v);
}
}
}
return d[T];
}
int DFS(int u,int lim){
if(u==T)return lim;
int f=0,tmp;
for(int i=hd[u];i;i=e[i].nxt){
int v=e[i].v;
if(d[v]==d[u]+1 && e[i].f && (tmp=DFS(v,min(lim,e[i].f)))){
e[i].f-=tmp;
e[i^1].f+=tmp;
lim-=tmp;
f+=tmp;
if(!lim)return f;
}
}
d[u]=0;
return f;
}
int Dinic(){
int res=0;
while(BFS())res+=DFS(S,INF);
return res;
}
int n,m;
int a[105];
int mp[105][105];
int id[105][105],ict=0;
int idw[1005];
bool vis[1005];
LL smm=0;
void Build(){
S=0;
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
id[i][j]=++ict;
}
}
for(int i=1;i<=n;i++){
if(!vis[a[i]]){
vis[a[i]]=1;
idw[a[i]]=++ict;
}
}
T=ict+n+1;
memset(vis,0,sizeof vis);
for(int i=1;i<=n;i++){
if(!vis[a[i]]){
vis[a[i]]=1;
insert(idw[a[i]],T,m*a[i]*a[i]);
}
}
for(int i=1;i<=n;i++){//zhonglei
insert(ict+i,idw[a[i]],INF);
insert(ict+i,T,a[i]);
}
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
if(mp[i][j]>0){
smm+=mp[i][j];
insert(S,id[i][j],mp[i][j]);
insert(id[i][j],ict+i,INF);
insert(id[i][j],ict+j,INF);
}
else if(mp[i][j]<0){
insert(id[i][j],T,-mp[i][j]);
insert(id[i][j],ict+i,INF);
insert(id[i][j],ict+j,INF);
}
if(i!=j){
insert(id[i][j],id[i+1][j],INF);
insert(id[i][j],id[i][j-1],INF);
}
}
}
return ;
}
int main(){
int i,j;
n=read();m=read();
for(int i=1;i<=n;i++)a[i]=read();
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
mp[i][j]=read();
Build();
int res=Dinic();
smm-=res;
printf("%lld\n",smm);
return 0;
}