题面:
思路:
有些点入,有些点出,每条边上都有价值.,....
多么完美的最大费用最大流!
那么怎么实现让每条边上的价值只被计算一次呢?
建两条边,一条边费用为这条边的价值,流量为1,另一条边费用0,流量inf即可
然后入口和出口连源汇点,跑最大费用最大流即可
欧拉!
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define inf 1e9 6 #define id(i,j) (i-1)*(n+1)+j 7 using namespace std; 8 inline int read(){ 9 int re=0,flag=1;char ch=getchar(); 10 while(ch<‘0‘||ch>‘9‘){ 11 if(ch==‘-‘) flag=-1; 12 ch=getchar(); 13 } 14 while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar(); 15 return re*flag; 16 } 17 int n,m,p,q,cnt,ans,flow,first[1000],dis[1000],pre[1000],path[1000]; 18 bool vis[1000]; 19 struct edge{ 20 int to,next,w,cap; 21 }a[200010]; 22 inline void add(int u,int v,int w,int cap){ 23 a[++cnt]=(edge){v,first[u],-w,cap};first[u]=cnt; 24 a[++cnt]=(edge){u,first[v],w,0};first[v]=cnt; 25 } 26 bool spfa(int s,int t){ 27 memset(pre,-1,sizeof(pre));memset(path,-1,sizeof(path)); 28 memset(vis,0,sizeof(vis)); 29 int u,v,i,q[5010],head=0,tail=1; 30 for(i=s;i<=t;i++) dis[i]=inf; 31 q[0]=s;dis[s]=0;vis[s]=1; 32 while(head<tail){ 33 u=q[head++];vis[u]=0; 34 for(i=first[u];~i;i=a[i].next){ 35 v=a[i].to; 36 if(dis[u]+a[i].w<dis[v]&&a[i].cap>0){ 37 dis[v]=dis[u]+a[i].w; 38 pre[v]=u;path[v]=i; 39 if(!vis[v]) q[tail++]=v,vis[v]=1; 40 } 41 } 42 } 43 return ~pre[t]; 44 } 45 void mcmf(int s,int t){ 46 int u,f; 47 while(spfa(s,t)){ 48 f=inf; 49 for(u=t;u!=s;u=pre[u]) f=min(f,a[path[u]].cap); 50 flow+=f;ans+=f*dis[t]; 51 for(u=t;u!=s;u=pre[u]){ 52 a[path[u]].cap-=f; 53 a[path[u]^1].cap+=f; 54 } 55 } 56 } 57 void init(){ 58 memset(first,-1,sizeof(first));memset(a,0,sizeof(a)); 59 cnt=-1;ans=0;flow=0; 60 } 61 int main(){ 62 freopen("shinkai.in","r",stdin); 63 freopen("shinkai.out","w",stdout); 64 init(); 65 int i,j,t1,t2,t3; 66 p=read();q=read();m=read();n=read(); 67 for(i=1;i<=m+1;i++){ 68 for(j=1;j<=n;j++){ 69 t1=read(); 70 add(id(i,j),id(i,j+1),t1,1); 71 add(id(i,j),id(i,j+1),0,inf); 72 } 73 } 74 for(j=1;j<=n+1;j++){ 75 for(i=1;i<=m;i++){ 76 t1=read(); 77 add(id(i,j),id(i+1,j),t1,1); 78 add(id(i,j),id(i+1,j),0,inf); 79 } 80 } 81 for(i=1;i<=p;i++){ 82 t1=read();t2=read();t3=read(); 83 add(0,id(t2+1,t3+1),0,t1); 84 } 85 for(i=1;i<=q;i++){ 86 t1=read();t2=read();t3=read(); 87 add(id(t2+1,t3+1),id(n+1,m+1)+1,0,t1); 88 } 89 mcmf(0,id(n+1,m+1)+1); 90 printf("%d",-ans); 91 }