UVA12433 Rent a Car
Posted 2017gdgzoi44
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA12433 Rent a Car相关的知识,希望对你有一定的参考价值。
这题应该算是比较难的一道网络流的题,(但却在我校OJ考试上出现了),但是大家只要能理解此图的建边方式就行。
假设有5天的租车需求,虚拟出2*n+2 即 12个节点,0为源点,12为汇点。
1,源点到1 2 3 4 5流量为r[i],费用为0。6 7 8 9 10到汇点流量为r[i-n],费用为0。
此题为一个检验能否满流且求满流花费最小的问题。
2,虚拟第2n+1个节点为买车途径,源点到2n+1节点花费为p[i],流量为c[i],多重边。
3,对于每一个i+n节点,其来源有两个,一个是
2*n+1节点,即购买新车,一个是之前的车辆送去维修后的可用车辆。连接i和i+1节点,流量为INF,花费为0。
4,同时根据维修的天数
连接i和d[j]+i+1+n节点,花费为s[i],流量为INF。
做完连边之后就跑一趟最小费用最大流模板,如最大流等于每天需要的车辆和,输出最小费用,否则,输出impossible。
#include<bits/stdc++.h>
using namespace std;
bool vis[400001];
int n,m,s,t,x,y,z,f,dis[400001],pre[400001],last[400001],flow[400001],maxflow,mincost,hh,hhh,ss,c,r,a[400001],b[400001];
struct Edge
int to,next,flow,dis;
edge[400001];
int head[400001],cnt;
queue <int> q;
void add(int from,int to,int flow,int dis)
edge[cnt].next=head[from];
edge[cnt].to=to;
edge[cnt].flow=flow;
edge[cnt].dis=dis;
head[from]=cnt++;
bool spfa(int s,int t)
memset(dis,0x7f,sizeof(dis));
memset(flow,0x7f,sizeof(flow));
memset(vis,0,sizeof(vis));
q.push(s); vis[s]=1; dis[s]=0; pre[t]=-1;
while(!q.empty())
int now=q.front();
q.pop();
vis[now]=0;
for (int i=head[now]; i!=-1; i=edge[i].next)
if (edge[i].flow>0 && dis[edge[i].to]>dis[now]+edge[i].dis)
dis[edge[i].to]=dis[now]+edge[i].dis;
pre[edge[i].to]=now;
last[edge[i].to]=i;
flow[edge[i].to]=min(flow[now],edge[i].flow);
if (!vis[edge[i].to])
vis[edge[i].to]=1;
q.push(edge[i].to);
return pre[t]!=-1;
void MCMF()
while(spfa(s,t))
int now=t;
maxflow+=flow[t];
mincost+=flow[t]*dis[t];
while(now!=s)
edge[last[now]].flow-=flow[t];
edge[last[now]^1].flow+=flow[t];
now=pre[now];
int read()
char ch=getchar();
int num=0;
while(ch<'0'||ch>'9')
ch=getchar();
while(ch<='9'&&ch>='0')
num=num*10+ch-'0';
ch=getchar();
return num;
int main()
hh=read();
hhh=hh;
while(hh--)
maxflow=0;
mincost=0;
printf("Case %d: ",hhh-hh);
ss=0;
cnt=0;
memset(head,-1,sizeof(head));
n=read();
c=read();
r=read();
t=2*n+1;
s=0;
for(int i=1;i<=n;i++)
if(i!=n)
add(i,i+1,99999999,0);
add(i+1,i,0,0);
for(int i=1;i<=n;i++)
x=read();
add(i,t,x,0);
add(t,i,0,0);
add(s,i+n,x,0);
add(i+n,s,0,0);
ss+=x;
for(int i=1;i<=c;i++)
x=read();
y=read();
add(s,1,x,y);
add(1,s,0,-y);
for(int i=1;i<=r;i++)
a[i]=read();
b[i]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=r;j++)
if(i+a[j]+1<=n)
add(n+i,i+a[j]+1,99999999,b[j]);
add(i+a[j]+1,n+i,0,-b[j]);
MCMF();
if(maxflow==ss)
printf("%d\n",mincost);
else
puts("impossible");
以上是关于UVA12433 Rent a Car的主要内容,如果未能解决你的问题,请参考以下文章
UVA - 12661 Funny Car Racing (Dijkstra算法)
UVa 12661 Funny Car Racing (dijkstra)
UVa 12661 - Funny Car Racing(Dijkstra)