CF802C Heidi and Library(hard)

题意:

标程:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=205;
 4 const int inf=0x3f3f3f3f;
 5 struct node{int to,next,w,c;}num[N*10];
 6 queue<int> q;
 7 int cnt=1,sc,S,T,dis[N],head[N],n,a[N],c[N],ans,k,pre[N],prevv[N],preve[N],t[1000005];
 8 void add(int x,int y,int w,int c)
 9 {num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;num[cnt].c=c;head[x]=cnt;
10 num[++cnt].to=x;num[cnt].next=head[y];num[cnt].w=-w;num[cnt].c=0;head[y]=cnt;}
11 
12 void build()
13 {
14     for (int i=1;i<n;i++) add(i,i+1,0,k-1);
15     for (int i=1;i<=n;i++)
16       if (pre[i]&&pre[i]!=i-1)
17       {
18             add(S,pre[i]+1,0,1);
19             add(pre[i]+1,++sc,0,1);
20             add(i,sc,-c[a[i]],1);
21             add(sc,T,0,1);
22       }
23 }
24 void spfa()
25 {
26     q.push(S);memset(dis,inf,sizeof(dis));
27     dis[S]=0;
28     while (!q.empty())
29     {
30         int now=q.front();q.pop();
31         for (int i=head[now];i;i=num[i].next)
32           if (num[i].c&&dis[num[i].to]>dis[now]+num[i].w)
33           {
34                 dis[num[i].to]=dis[now]+num[i].w,q.push(num[i].to);
35                 prevv[num[i].to]=now;preve[num[i].to]=i;
36           }
37             
38     }
39 }
40 void solve()
41 {
42     while (1==1)
43     {
44         spfa();
45        if (dis[T]==inf) break;
46        int sum=0;
47        for (int i=T,it;i!=S;i=prevv[i]) 
48           it=preve[i],sum+=num[it].w,num[it].c--,num[it^1].c++;
49        ans+=sum;
50     } 
51 }
52 int main()
53 {
54     scanf("%d%d",&n,&k);
55     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
56     for (int i=1;i<=n;i++) scanf("%d",&c[i]); 
57     for (int i=1;i<=n;i++) 
58     {
59       pre[i]=t[a[i]];t[a[i]]=i;
60       if (i==1||pre[i]!=i-1) ans+=c[a[i]]; 
61     }
62     S=n+1;T=sc=S+1;
63     build();solve();
64     printf("%d\n",ans); 
65     return 0;
66 }

题解:最小费用最大流

猜你喜欢

转载自www.cnblogs.com/Scx117/p/9090671.html