loj6045 「雅礼集训 2017 Day8」价

我们考虑最小割。

我一开始觉得是裸的最小割,就直接S到每个减肥药连up+p[i]的边,减肥药到药材连inf边,药材到T连up,然后得到了40分的好成绩。

之后我发现这是一个假的最小割,最小割割的是代价或者得不到的收益,上面说的这种建图左边割掉的是收益,右边割掉的是代价,然后当然就gg了。

所以我们把p取相反数,因为有负权,我们在给所有边加上一个UP,之后就可以直接建图最小割了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #define UP 2000000
 8 #define inf 0x7fffffff
 9 #define N 666
10 using namespace std;
11 int e=2,head[N];
12 struct edge{
13     int u,v,f,next;
14 }ed[N*N];
15 void add(int u,int v,int f){
16     ed[e].u=u;ed[e].v=v;ed[e].f=f;
17     ed[e].next=head[u];head[u]=e++;
18     ed[e].u=v;ed[e].v=u;ed[e].f=0;
19     ed[e].next=head[v];head[v]=e++;
20 }
21 int n,ans,S,T,dep[N];
22 bool bfs(){
23     memset(dep,0,sizeof dep);
24     queue<int> q;q.push(S);dep[S]=1;
25     while(!q.empty()){
26         int x=q.front();q.pop();
27         for(int i=head[x];i;i=ed[i].next){
28             if(ed[i].f&&!dep[ed[i].v]){
29                 dep[ed[i].v]=dep[x]+1;
30                 if(ed[i].v==T)return 1;
31                 q.push(ed[i].v);
32             }
33         }
34     }
35     return 0;
36 }
37 int dfs(int x,int f){
38     if(x==T||!f)return f;
39     int ans=0;
40     for(int i=head[x];i;i=ed[i].next){
41         if(ed[i].f&&dep[ed[i].v]==dep[x]+1){
42             int nxt=dfs(ed[i].v,min(f,ed[i].f));
43             ans+=nxt,f-=nxt;ed[i].f-=nxt,ed[i^1].f+=nxt;
44             if(!f)break;
45         }
46     }
47     if(!ans)dep[x]=-1;
48     return ans;
49 }
50 int dinic(){
51     int ans=0;
52     while(bfs())ans+=dfs(S,inf);
53     return ans;
54 }
55 int main(){
56     // freopen("test.in","r",stdin);
57     scanf("%d",&n);
58     S=2*n+1;T=S+1;
59     for(int i=1,j,k;i<=n;i++){
60         scanf("%d",&j);
61         while(j--){
62             scanf("%d",&k);
63             add(i,n+k,inf);
64         }
65     }
66     for(int i=1,x;i<=n;i++){
67         scanf("%d",&x);
68         add(S,i,UP-x);
69         add(n+i,T,UP);
70         ans-=UP-x;
71     }
72     ans+=dinic();
73     printf("%d\n",ans);
74 }
View Code

 

posted @ 2018-04-12 09:17  Ren_Ivan  阅读(474)  评论(0编辑  收藏  举报