一开始我把每个店主都拆成k个点,然后建图。。然后TLE。。
看题解= =哦,愚钝了,k个商品是独立的,可以分别跑k次最小费用最大流,结果就是k次总和。。
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #define MAXN 111 8 #define MAXM 111*111*2 9 struct Edge{ 10 int u,v,cap,cost,next; 11 }edge[MAXM]; 12 int head[MAXN]; 13 int NV,NE,vs,vt; 14 15 void addEdge(int u,int v,int cap,int cost){ 16 edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost; 17 edge[NE].next=head[u]; head[u]=NE++; 18 edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost; 19 edge[NE].next=head[v]; head[v]=NE++; 20 } 21 bool vis[MAXN]; 22 int d[MAXN],pre[MAXN]; 23 bool SPFA(){ 24 for(int i=0;i<NV;++i){ 25 vis[i]=0; 26 d[i]=INF; 27 } 28 vis[vs]=1; 29 d[vs]=0; 30 queue<int> que; 31 que.push(vs); 32 while(!que.empty()){ 33 int u=que.front(); que.pop(); 34 for(int i=head[u]; i!=-1; i=edge[i].next){ 35 int v=edge[i].v; 36 if(edge[i].cap && d[v]>d[u]+edge[i].cost){ 37 d[v]=d[u]+edge[i].cost; 38 pre[v]=i; 39 if(!vis[v]){ 40 vis[v]=1; 41 que.push(v); 42 } 43 } 44 } 45 vis[u]=0; 46 } 47 return d[vt]!=INF; 48 } 49 int MCMF(){ 50 int res=0; 51 while(SPFA()){ 52 int flow=INF,cost=0; 53 for(int u=vt; u!=vs; u=edge[pre[u]].u){ 54 flow=min(flow,edge[pre[u]].cap); 55 } 56 for(int u=vt; u!=vs; u=edge[pre[u]].u){ 57 edge[pre[u]].cap-=flow; 58 edge[pre[u]^1].cap+=flow; 59 cost+=flow*edge[pre[u]].cost; 60 } 61 res+=cost; 62 } 63 return res; 64 } 65 66 int n,m,k,mat[55][55][55],to[55][55],from[55][55]; 67 bool isOK(int *need,int *supply){ 68 for(int i=0; i<k; ++i) if(need[i]>supply[i]) return 0; 69 return 1; 70 } 71 int main(){ 72 int a; 73 while(~scanf("%d%d%d",&n,&m,&k) && (n||m||k)){ 74 int sum=0; 75 int supply[55]={0},need[55]={0}; 76 for(int i=0; i<n; ++i){ 77 for(int j=0; j<k; ++j){ 78 scanf("%d",&to[i][j]); 79 need[j]+=to[i][j]; 80 } 81 } 82 for(int i=0; i<m; ++i){ 83 for(int j=0; j<k; ++j){ 84 scanf("%d",&from[i][j]); 85 supply[j]+=from[i][j]; 86 } 87 } 88 for(int z=0; z<k; ++z){ 89 for(int x=0; x<n; ++x){ 90 for(int y=0; y<m; ++y) scanf("%d",&mat[z][x][y]); 91 } 92 } 93 if(!isOK(need,supply)){ 94 puts("-1"); 95 continue; 96 } 97 98 vs=n+m; vt=vs+1; NV=n+m+2; 99 int res=0; 100 for(int good=0; good<k; ++good){ 101 NE=0; 102 memset(head,-1,sizeof(head)); 103 104 for(int i=0; i<m; ++i) addEdge(vs,i,from[i][good],0); 105 for(int i=0; i<n; ++i) addEdge(i+m,vt,to[i][good],0); 106 for(int i=0; i<n; ++i){ 107 for(int j=0; j<m; ++j) addEdge(j,i+m,INF,mat[good][i][j]); 108 } 109 res+=MCMF(); 110 } 111 printf("%d\n",res); 112 } 113 return 0; 114 }
时间: 2024-10-31 00:23:20