您的位置:首页 > 其它

HOJ 2543 Stone IV

2013-10-06 13:34 323 查看
传说中的凸费用流问题,对于一条有c1容量免费,超出容量部分增加的每单位流量费用为c2的边(u,v),在原图中拆成两条边(u,v,c1,0),(u,v,INF,c2)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#define maxn 1010
#define maxm 200010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int N,M,C,P;
struct MCMF{
int src,sink,e,n;
int first[maxn];
int cap[maxm],cost[maxm],v[maxm],next[maxm];
bool flag;
void init(){
e = 0;
memset(first,-1,sizeof(first));
}

void add_edge(int a,int b,int cc,int ww){
//printf("add:%d to %d,cap = %d,cost = %d\n",a,b,cc,ww);
cap[e] = cc;cost[e] = ww;v[e] = b;
next[e] = first[a];first[a] = e++;
cap[e] = 0;cost[e] = -ww;v[e] = a;
next[e] = first[b];first[b] = e++;
}

int d[maxn],pre[maxn],pos[maxn];
bool vis[maxn];

bool spfa(int s,int t){
memset(pre,-1,sizeof(pre));
memset(vis,0,sizeof(vis));
queue<int> Q;
for(int i = 0;i <= n;i++)   d[i] = INF;
Q.push(s);pre[s] = s;d[s] = 0;vis[s] = 1;
while(!Q.empty()){
int u = Q.front();Q.pop();
vis[u] = 0;
for(int i = first[u];i != -1;i = next[i]){
if(cap[i] > 0 && d[u] + cost[i] < d[v[i]]){
d[v[i]] = d[u] + cost[i];
pre[v[i]] = u;pos[v[i]] = i;
if(!vis[v[i]])  vis[v[i]] = 1,Q.push(v[i]);
}
}
}
return pre[t] != -1;
}

LL Mincost;
int Maxflow;

int MinCostFlow(int s,int t,int nn){
Mincost = 0,Maxflow = 0,n = nn;
while(spfa(s,t)){
LL min_f = INF;
for(int i = t;i != s;i = pre[i])
if(cap[pos[i]] < min_f) min_f = cap[pos[i]];
Mincost += d[t] * min_f;
Maxflow += min_f;
if(Mincost > C){
Maxflow -= ceil((Mincost - C) * 1.0 / d[t]);
break;
}
for(int i = t;i != s;i = pre[i]){
cap[pos[i]] -= min_f;
cap[pos[i]^1] += min_f;
}
}
return Mincost;
}
};

MCMF g;

int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&N,&M,&C,&P);
g.init();
int src = N+1,sink = 2;
g.add_edge(src,1,INF,P);
for(int i = 1;i <= M;i++){
int u,v,c1,c2;
scanf("%d%d%d%d",&u,&v,&c1,&c2);
u++;v++;
g.add_edge(u,v,c1,0);
g.add_edge(v,u,c1,0);
g.add_edge(u,v,INF,c2);
g.add_edge(v,u,INF,c2);
}
g.MinCostFlow(src,sink,src);
printf("%d\n",g.Maxflow);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: