题目大意:给你一个$n$个点,$m$条有向边的图,每个点有一个点权$a_i$,同时你可以用$b_i$的代价将$a_i$变为$0$
另外你要付出$sumlimits_{i=1}^nmaxlimits_{(i,j)}a_j$这么多代价。请最小化代价。
数据范围:$n≤1000$,$m≤50000$。
貌似是一道套路最小割
把每个点拆成两个点,对每条边新建一个点,将一个点的出边按终点的$a$从大到小排序后建图如下
该建图方式,只有让某个前缀$a_i$全部变为$0$,一个点产生的费用才会改变,这个建图保证了如果要割$a_i$就必须要割掉$b_1$至$b_{i-1}$,且不会割掉两个$a$
我们对每个点都这么建一波,然后跑个最大流就没了
orzlyy!!!!!
1 #include<bits/stdc++.h> 2 #define M 60005 3 #define INF (1<<30) 4 using namespace std; 5 6 struct edge{int u,v,next;}e[M*4]={0}; int head[M]={0},use=0; 7 void add(int x,int y,int z){e[use].u=y;e[use].v=z;e[use].next=head[x];head[x]=use++;} 8 void Add(int x,int y,int z){add(x,y,z); add(y,x,0);} 9 int dis[M]={0},S,T; queue<int> q; 10 bool bfs(){ 11 memset(dis,0,sizeof(dis)); 12 dis[S]=1; q.push(S); 13 while(!q.empty()){ 14 int u=q.front(); q.pop(); 15 for(int i=head[u];~i;i=e[i].next) 16 if(dis[e[i].u]==0&&e[i].v){ 17 dis[e[i].u]=dis[u]+1; 18 q.push(e[i].u); 19 } 20 } 21 return dis[T]; 22 } 23 int dfs(int x,int flow){ 24 if(x==T) return flow; int sum=0; 25 for(int i=head[x];~i;i=e[i].next) 26 if(dis[x]+1==dis[e[i].u]&&e[i].v){ 27 int k=dfs(e[i].u,min(flow,e[i].v)); 28 sum+=k; flow-=k; 29 e[i].v-=k; e[i^1].v+=k; 30 if(flow==0) return sum; 31 } 32 if(sum==0) dis[x]=-1; 33 return sum; 34 } 35 int dinic(){ 36 int res=0; 37 while(bfs()) 38 res+=dfs(S,INF); 39 return res; 40 } 41 42 int n,m,a[M]={0},b[M]={0}; 43 vector<int> g[M]; 44 bool cmp(int x,int y){return a[x]>a[y];} 45 void ReadData(){ 46 memset(head,-1,sizeof(head)); 47 scanf("%d%d",&n,&m); 48 for(int i=1;i<=n;i++) scanf("%d",a+i); 49 for(int i=1;i<=n;i++) scanf("%d",b+i); 50 for(int i=1;i<=m;i++){ 51 int x,y; scanf("%d%d",&x,&y); 52 g[x].push_back(y);// g[y].push_back(x); 53 } 54 } 55 void build(){ 56 S=0; T=2*n+1; int N=2*n+1; 57 for(int i=1;i<=n;i++) Add(S,i,INF); 58 for(int i=1;i<=n;i++) Add(i+n,T,b[i]); 59 for(int x=1;x<=n;x++){ 60 sort(g[x].begin(),g[x].end(),cmp); 61 for(int i=0;i<g[x].size();i++){ 62 N++; 63 Add(i?N-1:x,N,a[g[x][i]]); 64 Add(N,n+g[x][i],INF); 65 } 66 } 67 } 68 int main(){ 69 ReadData(); 70 build(); 71 cout<<dinic()<<endl; 72 }