标签:des blog http os io strong for ar
| Time Limit: 4000MS | Memory Limit: 65536K | |
| Total Submissions: 13531 | Accepted: 4635 |
Description
Input
Output
Sample Input
1 3 3 1 1 1 0 1 1 1 2 2 1 0 1 1 2 3 1 1 1 2 1 1 1 1 1 3 2 20 0 0 0
Sample Output
4 -1
给出的物品的种类太多,不同的供应商对不同的店家供应不同的货物的花费不同,这样是同一个图中的边太多,直接建图会超时,所以,对每一种货物分别建图,求出每一种的货物的最小花费,得到最终的花费
感谢http://blog.csdn.net/scf0920/article/details/38707085
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
#define maxn 60
#define INF 0x3f3f3f3f
struct node
{
int v , w , s ;
int next ;
} p[100000];
int nk[maxn][maxn] , mk[maxn][maxn] , cnt ;//nk存储不同的店家对不同货物的需求,mk,不同的供应商对不同货物的供应量
int head[maxn<<2] , vis[maxn<<2] , dis[maxn<<2] , pre[maxn<<2] ;
queue <int> q ;
void add(int u,int v,int w,int s)
{
p[cnt].v = v ;
p[cnt].w = w ;
p[cnt].s = s ;
p[cnt].next = head[u] ;
head[u] = cnt++ ;
p[cnt].v = u ;
p[cnt].w = 0 ;
p[cnt].s = -s ;
p[cnt].next = head[v] ;
head[v] = cnt++ ;
}
int spfa(int s,int t)
{
int u , v , i ;
memset(dis,INF,sizeof(dis));
vis[s] = 1 ; dis[s] = 0 ;
pre[s] = pre[t] = -1 ;
while( !q.empty() )
q.pop();
q.push(s);
while( !q.empty() )
{
u = q.front();
q.pop();
vis[u] = 0 ;
for(i = head[u] ; i != -1 ; i = p[i].next)
{
v= p[i].v ;
if( p[i].w && dis[v] > dis[u] + p[i].s )
{
dis[v] = dis[u] + p[i].s ;
pre[v] = i ;
if( !vis[v] )
{
vis[v] = 1 ;
q.push(v);
}
}
}
}
if( pre[t] == -1 )
return 0;
return 1 ;
}
int f(int s,int t,int k)
{
int ans_s = 0 , ans_w = 0 , min1 , i ;//ans_s存储最小花费,ans_w存储一共的流量
memset(vis,0,sizeof(vis));
memset(pre,-1,sizeof(pre));
while( spfa(s,t) )
{
min1 = INF ;
for(i = pre[t] ; i != -1 ; i = pre[ p[i^1].v ])
if( p[i].w < min1 )
min1 = p[i].w ;
for(i = pre[t] ; i != -1 ; i = pre[ p[i^1].v ])
{
p[i].w -= min1 ;
p[i^1].w += min1 ;
ans_s += min1*p[i].s ;
}
ans_w += min1 ;
}
if(ans_w == nk[0][k])
return ans_s ;
return -1;
}
int main()
{
int i , j , n , m , kk , k , x , ans , flag ;//输入很复杂,尤其是不同的供应商对不同的店家供应不同的货物有不同的价格。
while(scanf("%d %d %d", &n, &m, &k) && n+m+k != 0)
{
/*建图方式,对每种货物分别建图,对于第ki种货物的建图:由源点到每个供应商(容量是供应的货物的量,花费是0),由供应商到店家(容量是INF,花费是供应ki货物的价格)
,有店家到汇点建图(容量是店家需要的货物的量,花费是0)*/
memset(nk,0,sizeof(nk));
for(i = 1 ; i <= n ; i++)
for(j = 1 ; j <= k ; j++)
{
scanf("%d", &nk[i][j]);
nk[0][j] += nk[i][j] ;//nk[0][]储存下一共需要第j样货物的数量
}
for(i = 1 ; i <= m ; i++)
for(j = 1 ; j <= k ; j++)
scanf("%d", &mk[i][j]);
ans = flag = 0 ;//flag判断之前的货物是不是都可以供应足够,如果不够,不用向下在计算。
for(kk = 1 ; kk <= k ; kk++)
{
cnt = 0 ;
memset(head,-1,sizeof(head));
for(i = 1 ; i <= m ; i++)
add(0,i,mk[i][kk],0);
for(i = 1 ; i <= n ; i++)
add(m+i,m+n+1,nk[i][kk],0);
for(i = 1 ; i <= n ; i++)
for(j = 1 ; j <= m ; j++)
{
scanf("%d", &x);
add(j,m+i,INF,x);
}
if(flag != -1)
{
flag = f(0,n+m+1,kk);
if(flag != -1)
ans += flag ;
}
}
if(flag == -1)
printf("-1\n");
else
printf("%d\n", ans);
}
return 0;
}
poj2516--Minimum Cost(费用流,分别建图),布布扣,bubuko.com
poj2516--Minimum Cost(费用流,分别建图)
标签:des blog http os io strong for ar
原文地址:http://blog.csdn.net/winddreams/article/details/38711797