1. 程式人生 > >BZOJ_4873_[Shoi2017]壽司餐廳_最大權閉合子圖

BZOJ_4873_[Shoi2017]壽司餐廳_最大權閉合子圖

子圖 pop ret spa lld ace include www scanf

BZOJ_4873_[Shoi2017]壽司餐廳_最大權閉合子圖

題意:http://www.lydsy.com/JudgeOnline/problem.php?id=4873

分析:我們發現分數正負都有,並且之間有依賴關系,很容易想到最大權閉合子圖。

建圖:

1.S向正點連邊,負點向T連邊。

2.選了[i~j]顯然要選[i+1~j]和[i~j-1],分別連邊。

3.對於i==j的點,向對應的壽司連邊。

4.總花費m*x*x+c*x拆成兩部分。對於每個代號x,向T連容量為m*x*x的邊,c*x這部分我們考慮算f[i][i]時把f[i][i]的值減掉x,當然也可以每個壽司向T連容量為x的邊。

完了。

代碼:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 #define inf 100000000
 7 #define LL long long
 8 #define S (30000)
 9 #define T (30001)
10 int d[110][110],n,m;
11 int head[31000],to[4000000],nxt[4000000],cnt=1;
12 int dep[31000],a[110],tot,idx[110
][110],mxn; 13 LL flow[4000000],sum; 14 inline void add(int u,int v,LL f) 15 { 16 to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;flow[cnt]=f; 17 to[++cnt]=u;nxt[cnt]=head[v];head[v]=cnt;flow[cnt]=0; 18 } 19 bool bfs() 20 { 21 queue <int> q; 22 memset(dep,0,sizeof(dep)); 23 dep[S]=1;q.push(S);
24 while(!q.empty()) 25 { 26 int x=q.front();q.pop(); 27 for(int i=head[x];i;i=nxt[i]) 28 { 29 if(!dep[to[i]]&&flow[i]) 30 { 31 dep[to[i]]=dep[x]+1; 32 if(to[i]==T)return 1; 33 q.push(to[i]); 34 } 35 } 36 } 37 return 0; 38 } 39 LL dfs(int x,LL mf) 40 { 41 if(x==T)return mf; 42 LL nf=0; 43 for(int i=head[x];i;i=nxt[i]) 44 { 45 if(dep[to[i]]==dep[x]+1&&flow[i]) 46 { 47 int tmp=dfs(to[i],min(flow[i],mf-nf)); 48 nf+=tmp; 49 flow[i]-=tmp; 50 flow[i^1]+=tmp; 51 if(nf==mf)break; 52 } 53 } 54 dep[x]=0; 55 return nf; 56 } 57 void dinic() 58 { 59 LL f; 60 while(bfs()) 61 { 62 while(f=dfs(S,inf)) 63 sum-=f; 64 } 65 printf("%lld",sum); 66 } 67 int main() 68 { 69 register int i,j; 70 scanf("%d%d",&n,&m); 71 for(i=1;i<=n;i++) 72 for(j=i;j<=n;j++) 73 idx[i][j]=++tot; 74 for(i=1;i<=n;i++)scanf("%d",&a[i]),mxn=max(mxn,a[i]); 75 for(i=1;i<=mxn;i++)add(tot+i,T,m*i*i); 76 for(i=1;i<=n;i++)add(idx[i][i],tot+a[i],inf); 77 for(i=1;i<=n;i++) 78 { 79 for(j=i;j<=n;j++) 80 { 81 scanf("%d",&d[i][j]); 82 if(i==j)d[i][j]-=a[i]; 83 else{ 84 add(idx[i][j],idx[i+1][j],inf); 85 add(idx[i][j],idx[i][j-1],inf); 86 } 87 if(d[i][j]>0) 88 { 89 sum+=d[i][j]; 90 add(S,idx[i][j],d[i][j]); 91 } 92 else{ 93 add(idx[i][j],T,-d[i][j]); 94 } 95 } 96 } 97 dinic(); 98 }

BZOJ_4873_[Shoi2017]壽司餐廳_最大權閉合子圖