洛谷P4012 深海機器人問題(費用流)
阿新 • • 發佈:2018-08-20
problem class spf int const 還得 一個點 png pty
傳送門
圖給的好坑……還得倒過來……
用大佬的圖做個示範
我們考慮左圖吧
把每一個點向下連邊,容量$1$,費用為給出的價值(表示一個機器人可以過去取得標本)
再連一條邊,容量$inf$,費用$0$(表示剩下的機器人過去無法取得標本)
然後向右連的邊也一樣
註意連邊的順序
然後源點向所有出發點連邊,容量為機器人數,費用$0$,所有目的地向匯點連邊,容量為機器人數,費用為$0$
跑個最大費用流
1 //minamoto 2 #include<bits/stdc++.h> 3 #define inf 0x3f3f3f3f 4#define get(i,j) (i-1)*m+j 5 using namespace std; 6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 7 char buf[1<<21],*p1=buf,*p2=buf; 8 inline int read(){ 9 #define num ch-‘0‘ 10 char ch;bool flag=0;int res; 11 while(!isdigit(ch=getc()))12 (ch==‘-‘)&&(flag=true); 13 for(res=num;isdigit(ch=getc());res=res*10+num); 14 (flag)&&(res=-res); 15 #undef num 16 return res; 17 } 18 const int N=1005,M=100005; 19 int ver[M],edge[M],head[N],Next[M],flow[M],tot=1; 20 int dis[N],disf[N],vis[N],Pre[N],last[N],n,m,s,t,a,b;21 queue<int> q; 22 inline void add(int u,int v,int f,int e){ 23 ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e; 24 ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=0,edge[tot]=-e; 25 } 26 bool spfa(){ 27 memset(dis,0xef,sizeof(dis)); 28 q.push(s),dis[s]=0,disf[s]=inf,Pre[t]=-1; 29 while(!q.empty()){ 30 int u=q.front();q.pop();vis[u]=0; 31 for(int i=head[u];i;i=Next[i]){ 32 int v=ver[i]; 33 if(flow[i]&&dis[v]<dis[u]+edge[i]){ 34 dis[v]=dis[u]+edge[i],Pre[v]=u,last[v]=i; 35 disf[v]=min(disf[u],flow[i]); 36 if(!vis[v]) vis[v]=1,q.push(v); 37 } 38 } 39 } 40 return ~Pre[t]; 41 } 42 int dinic(){ 43 int maxcost=0; 44 while(spfa()){ 45 int u=t;maxcost+=disf[t]*dis[t]; 46 while(u!=s){ 47 flow[last[u]]-=disf[t]; 48 flow[last[u]^1]+=disf[t]; 49 u=Pre[u]; 50 } 51 } 52 return maxcost; 53 } 54 int main(){ 55 a=read(),b=read(),n=read()+1,m=read()+1; 56 s=0,t=n*m+1; 57 for(int i=1;i<=n;++i) 58 for(int j=1;j<m;++j){ 59 int x=read(),hh=get(i,j),tt=hh+1; 60 add(hh,tt,1,x); 61 add(hh,tt,inf,0); 62 } 63 for(int j=1;j<=m;++j) 64 for(int i=1;i<n;++i){ 65 int x=read(),hh=get(i,j),tt=hh+m; 66 add(hh,tt,1,x); 67 add(hh,tt,inf,0); 68 } 69 for(int i=1;i<=a;++i){ 70 int k=read(),x=read()+1,y=read()+1; 71 add(s,get(x,y),k,0); 72 } 73 for(int i=1;i<=b;++i){ 74 int k=read(),x=read()+1,y=read()+1; 75 add(get(x,y),t,k,0); 76 } 77 printf("%d\n",dinic()); 78 return 0; 79 }
洛谷P4012 深海機器人問題(費用流)