您的位置:首页 > 其它

POJ2516 Minimum Cost(K次费用流)

2016-03-01 22:18 357 查看
链接:http://poj.org/problem?id=2516

题意太麻烦了,看懂题意之后就很简单了。。。不解释题意了。。。

思路:事先判断一下物品够不够。然后对每个物品建图跑费用流。建图的时候要小心,容易写错。

直接上代码吧

#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<map>
#include<iostream>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<cctype>
#include<set>
#include<ctime>
#include<cassert>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int INF=1e9+7;
#define MP make_pair
#define PB push_back

struct node{
int cap,cost;
}G[110][110];
int n,m,k,st,ed,need[55][55],save[55][55],pic[55][55][55];
int d[110],pre[110],flow[110];
bool vis[110];
void input(){
for(int i=1;i<=n;i++){
for(int j=1;j<=k;j++){
scanf("%d",&need[i][j]);//need
[k]
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=k;j++){
scanf("%d",&save[i][j]);//save[m][k]
}
}
for(int w=1;w<=k;w++){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&pic[w][i][j]);//pic[k]
[m]
}
}
}
}
bool check(){//判断一下是否不够
for(int w=1;w<=k;w++){
int sum=0;
for(int i=1;i<=m;i++){
sum+=save[i][w];
}
for(int i=1;i<=n;i++){
sum-=need[i][w];
}
if(sum<0)return false;
}
return true;
}

void build(int w){//对每一个物品建图
memset(G,0,sizeof G);
st=0;ed=n+m+1;
//st->m cap:save[m][w] cost:0
//n->ed cap:need
[w] cost:0
for(int i=1;i<=n;i++){
G[i+m][ed].cap=need[i][w];
}
for(int j=1;j<=m;j++){
G[st][j].cap=save[j][w];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
G[j][i+m].cap=save[j][w];
G[j][i+m].cost=pic[w][i][j];
G[i+m][j].cost=-pic[w][i][j];
}
}
}
bool spfa(int &ff,int &ans){
queue<int> Q;
Q.push(st);
fill(d,d+ed+1,INF);
d[st]=0;vis[st]=true;flow[st]=INF;pre[st]=-1;
while(!Q.empty()){
int s=Q.front();Q.pop();
vis[s]=false;
for(int i=1;i<=ed;i++){
if(G[s][i].cap>0&&d[i]>d[s]+G[s][i].cost){
d[i]=d[s]+G[s][i].cost;
pre[i]=s;
flow[i]=min(flow[s],G[s][i].cap);
if(!vis[i]){
vis[i]=true;Q.push(i);
}
}
}
}
if(d[ed]==INF)return false;
ff+=flow[ed];ans+=flow[ed]*d[ed];
int now=ed;
while(now!=st){
G[pre[now]][now].cap-=flow[ed];
G[now][pre[now]].cap+=flow[ed];
now=pre[now];
}
return true;
}
int main()
{
//    freopen("D://input.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k)!=EOF&&n&&m&&k){
input();
if(!check()){printf("-1\n");continue;}
int ff=0,ans=0;
for(int w=1;w<=k;w++){
build(w);
while(spfa(ff,ans));//printf("%d %d\n",ff,ans);
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: