具体说就是每条管道都有一个cost,要你在最大流情况下使总流量最小.
算法:
十分暴力,spfa跑能否增广同时每次走cost最小的路(就是最短路..),然后增广..
#include
using namespace std;
int n,m,s,t,to[100010],las[100010],head[5010],next[100010],pre[5010],cost[100010],dis[5010],num;bool inq[5010];
void read(int &x)
{
char c=getchar();x=0;int r=1;
while(c>'9'||c<'0')
{if(c=='-')r=-1;c=getchar();}
while(c<='9'&&c>='0')x=(x<<3)+(x<<1)+c-48,c=getchar();
x*=r;
}
void init()
{
memset(head,-1,sizeof head),
memset(next,-1,sizeof next),
num=-1;
}
void add_edge(int u,int v,int w,int f)
{
next[++num]=head[u],to[num]=v,
las[num]=w,cost[num]=f,head[u]=num;
}
bool spfa()
{
memset(inq,0,sizeof inq),
memset(pre,-1,sizeof pre),
memset(dis,127,sizeof dis);
queue<int>q;int nw,v;
dis[s]=0,inq[s]=1,q.push(s);
while(!q.empty())
{
nw=q.front(),q.pop(),inq[nw]=0;
for(int i=head[nw];i!=-1;i=next[i])
{
v=to[i];
if(las[i]!=0&&dis[v]>dis[nw]+cost[i])
{
dis[v]=dis[nw]+cost[i];
pre[v]=i;if(!inq[v])q.push(v);inq[v]=1;
}
}
}
return dis[t]<=1e9;
}
void mcmf()
{
int flow=0,nw=0,spd=0;
while(spfa())
{
nw=1e9;
for(int i=pre[t];i!=-1;i=pre[to[i^1]])nw=min(nw,las[i]);
for(int i=pre[t];i!=-1;i=pre[to[i^1]])las[i]-=nw,las[i^1]+=nw;
flow+=nw;spd+=nw*dis[t];
}
printf("%d %d",flow,spd);
}
int main()
{
init();int u,v,w,f;
read(n),read(m),read(s),read(t);
for(int i=1;i<=m;i++)
{
read(u),read(v),read(w),read(f);
add_edge(u,v,w,f),add_edge(v,u,0,-f);
}
mcmf();
return 0;
}