D - 文理分科 (网络流->最小割)

题目链接:https://cn.vjudge.net/contest/281959#problem/D

题目大意:中文题目

具体思路:我们需要求出最大的满意值,从另一方面想,我们可以求出总的满意值,然后再求出不符合情况的最小的代价,这两个相减,就能求出最大的满意值,这个时候就可以通过最小割来求了(最小割:使得整个图不连通的最小花费)。

 

这一篇博客讲的很好:https://blog.csdn.net/yakeding/article/details/79357545

AC代码:

  1 #include<iostream>
  2 #include<stack>
  3 #include<queue>
  4 #include<iomanip>
  5 #include<stdio.h>
  6 #include<cstring>
  7 #include<cstring>
  8 #include<cmath>
  9 #include<algorithm>
 10 #include<map>
 11 #include<vector>
 12 using namespace std;
 13 # define ll long long
 14 # define maxn 6000000+100
 15 # define inf 0x3f3f3f3f
 16 int prev[maxn];//边的编号
 17 int head[maxn];
 18 int f[2][4]= {{1,-1,0,0},{0,0,1,-1}};
 19 struct node
 20 {
 21     int to;
 22     int flow;
 23     int nex;
 24 } edge[maxn];
 25 int num,st,ed;
 26 void init()
 27 {
 28     memset(head,-1,sizeof(head));
 29     num=0;
 30 }
 31 void addedge(int fr,int to,int flow)
 32 {
 33     edge[num].to=to;
 34     edge[num].flow=flow;
 35     edge[num].nex=head[fr];
 36     head[fr]=num++;
 37     edge[num].to=fr;
 38     edge[num].flow=0;
 39     edge[num].nex=head[to];
 40     head[to]=num++;
 41 }
 42 bool bfs()
 43 {
 44     memset(prev,-1,sizeof(prev));
 45     prev[st]=1;
 46     queue<int>q;
 47     q.push(st);
 48     while(!q.empty())
 49     {
 50         int top=q.front();
 51         q.pop();
 52         for(int i=head[top]; i!=-1; i=edge[i].nex)
 53         {
 54             int temp=edge[i].to;
 55             if(prev[temp]==-1&&edge[i].flow>0)
 56             {
 57                 prev[temp]=prev[top]+1;
 58                 q.push(temp);
 59             }
 60         }
 61     }
 62     return prev[ed]!=-1;
 63 }
 64 int dfs(int u,int flow)
 65 {
 66     if(u==ed)
 67         return flow;
 68     int res=0;
 69     for(int i=head[u]; i!=-1; i=edge[i].nex)
 70     {
 71         int t=edge[i].to;
 72         if(prev[t]==(prev[u]+1)&&edge[i].flow>0)
 73         {
 74             int temp=dfs(t,min(flow,edge[i].flow));
 75             edge[i].flow-=temp;
 76             edge[i^1].flow+=temp;
 77             res+=temp;
 78             flow-=temp;
 79             if(flow==0)
 80                 break;
 81         }
 82     }
 83     if(res==0)
 84         prev[u]=-1;
 85     return res;
 86 }
 87 int n,m;
 88 int dinic()
 89 {
 90     int ans=0;
 91     while(bfs())
 92     {
 93         ans+=dfs(st,inf);
 94     }
 95     return ans;
 96 }
 97 bool judge(int t1,int t2)
 98 {
 99     if(t1>=1&&t1<=n&&t2>=1&&t2<=m)
100         return true;
101     return false;
102 }
103 int main()
104 {
105     init();
106     int sum=0;
107     int tmp;
108     st=1e5,ed=1e5+1;
109     scanf("%d %d",&n,&m);
110     for(int i=1; i<=n; i++)
111     {
112         for(int j=1; j<=m; j++)
113         {
114             scanf("%d",&tmp);
115             sum+=tmp;
116             addedge((i-1)*m+j,ed,tmp);
117         }
118     }
119     for(int i=1; i<=n; i++)
120     {
121         for(int j=1; j<=m; j++)
122         {
123             scanf("%d",&tmp);
124             sum+=tmp;
125             addedge(st,(i-1)*m+j,tmp);
126         }
127     }
128     for(int i=1; i<=n; i++)
129     {
130         for(int j=1; j<=m; j++)
131         {
132             scanf("%d",&tmp);
133             addedge((i-1)*m+j,((i-1)*m+j)+n*m,inf);
134             addedge(((i-1)*m+j)+n*m,ed,tmp);
135             sum+=tmp;
136             for(int k=0; k<4; k++)
137             {
138                 int x=i+f[0][k];
139                 int y=j+f[1][k];
140                 if(judge(x,y))
141                     addedge((x-1)*m+y,((i-1)*m+j)+n*m,inf);
142             }
143         }
144     }
145     for(int i=1; i<=n; i++)
146     {
147         for(int j=1; j<=m; j++)
148         {
149             scanf("%d",&tmp);
150             sum+=tmp;
151             addedge(((i-1)*m+j)+n*m*2,(i-1)*m+j,inf);
152             addedge(st,((i-1)*m+j)+n*m*2,tmp);
153             for(int k=0; k<4; k++)
154             {
155                 int x=i+f[0][k];
156                 int y=j+f[1][k];
157                 if(judge(x,y))
158                     addedge(((i-1)*m+j)+n*m*2,(x-1)*m+y,inf);
159             }
160         }
161     }
162    // cout<<1<<endl;
163     int ans=dinic();
164   //  cout<<1<<endl;
165     printf("%d\n",sum-ans);
166     return 0;
167 }

 

posted @ 2019-02-04 00:15  Let_Life_Stop  阅读(248)  评论(0编辑  收藏  举报