Address: poj 2516
I'm dizzy... This question comes up with the idea of separating each type of goods .. But I immediately gave up .. It seems that it is too time-consuming to request 50 fee streams .. Later, we decided to split the point. It took a long time to split it, and it had been TLE .. Even if it drops to 2600 points, it's also TLE .. Then I think of this separate method, and suddenly I feel that the fee flow of the 100 points is almost free of time .. A maximum of 50 requests can be obtained .. So I tried it...
Here, we should have known the idea. Is to separate each type of goods, because each type of goods is independent of each other. The idea of creating each graph is:
The source and supplier are connected, the traffic weight is the supply of goods such as the supplier, the cost weight is 0, the sink and the store are connected, the traffic weight is the amount of the goods required by the store, and the cost weight is 0. Then the supplier is connected to the corresponding store. The cost weight is the corresponding input value, and the traffic weight is INF.
The Code is as follows:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <set>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;const int maxn=300;int head[maxn], source, sink, cnt, flow, cost, sum, mpn[60][60], mpm[60][60];int d[maxn], vis[maxn], cur[maxn], f[maxn];struct node{ int u, v, cap, cost, next;} edge[3000000];void add(int u, int v, int cap, int cost){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].cost=cost; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].cost=-cost; edge[cnt].next=head[v]; head[v]=cnt++;}int spfa(){ memset(vis,0,sizeof(vis)); memset(d,INF,sizeof(d)); deque<int>q; q.push_back(source); d[source]=0; cur[source]=-1; f[source]=INF; while(!q.empty()) { int u=q.front(); q.pop_front(); vis[u]=0; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(d[v]>d[u]+edge[i].cost&&edge[i].cap) { d[v]=d[u]+edge[i].cost; f[v]=min(f[u],edge[i].cap); cur[v]=i; if(!vis[v]) { if(!q.empty()&&d[v]<d[q.front()]) { q.push_front(v); } else q.push_back(v); vis[v]=1; } } } } if(d[sink]==INF) return 0; flow+=f[sink]; cost+=d[sink]*f[sink]; for(int i=cur[sink]; i!=-1; i=cur[edge[i^1].v]) { edge[i].cap-=f[sink]; edge[i^1].cap+=f[sink]; } return 1;}int mcmf(){ flow=cost=0; while(spfa()) ; if(flow<sum) return -1; else return cost;}int main(){ int n, m, k, i, j, x, h, ans, flag; while(scanf("%d%d%d",&n,&m,&k)!=EOF&&n&&m&&k) { ans=0; flag=0; source=0; sink=n+m+1; for(i=1; i<=n; i++) { for(j=1; j<=k; j++) { scanf("%d",&mpn[i][j]); } } for(i=1; i<=m; i++) { for(j=1; j<=k; j++) { scanf("%d",&mpm[i][j]); } } for(h=1; h<=k; h++) { memset(head,-1,sizeof(head)); cnt=0; sum=0; for(i=1; i<=n; i++) { add(i+m,sink,mpn[i][h],0); sum+=mpn[i][h]; for(j=1;j<=m;j++) { scanf("%d",&x); add(j,i+m,INF,x); } } if(flag) continue ; for(i=1;i<=m;i++) { add(source,i,mpm[i][h],0); } int y=mcmf(); //printf("%d\n",y); if(y==-1) { flag=1; } else ans+=y; } if(flag) printf("-1\n"); else printf("%d\n",ans); } return 0;}