题目描述
如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
输入输出格式
输入格式:
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
输出格式:
一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。
输入输出样例
输入样例#1:
4 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5
输出样例#1:
50 280
说明
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,M<=10
对于70%的数据:N<=1000,M<=1000
对于100%的数据:N<=5000,M<=50000
分析:模板题
注意两点:1.判断时不能使用0x7f,原因是不能精准判断,只能大致估计,所以在memeset时最好使用0x33,这样在判断时的写法为dis[t]<0x33333333(8个3)
2.记得加快读
这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int INF=0x33333333;
const int N=1001000;
struct node{
int x,y,v,cost,next;
};
node way[N*2];
int st[N],tot=-1;
int n,m,s,t,flow=0,ans=0;
bool p[N];
int pre[N],dis[N]; ///
int in() //快读
{
int t=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-'0',ch=getchar();
return t;
}
void add(int u,int w,int z,int c)
{
tot++;
way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].cost=c;way[tot].next=st[u];st[u]=tot;
tot++;
way[tot].x=w;way[tot].y=u;way[tot].v=0;way[tot].cost=-c;way[tot].next=st[w];st[w]=tot;
}
int spfa()
{
int i;
memset(pre,0,sizeof(pre));
memset(p,1,sizeof(p));
memset(dis,0x33,sizeof(dis)); //花费 ////0x33
queue<int> q;
q.push(s);
dis[s]=0;
p[s]=0;
while (!q.empty())
{
int r=q.front();
q.pop();
for (i=st[r];i!=-1;i=way[i].next)
{
if (way[i].v&&dis[way[i].y]>dis[r]+way[i].cost) //
{
dis[way[i].y]=dis[r]+way[i].cost;
pre[way[i].y]=i; //记录一下修改来自哪条路
if (p[way[i].y])
{
p[way[i].y]=0;
q.push(way[i].y);
}
}
}
p[r]=1; ///
}
return dis[t]<INF;
}
void doit()
{
int sum,i;
while (spfa())
{
sum=INF; //增广量
for (i=t;i!=s;i=way[pre[i]].x) //从汇点反向增广
sum=min(sum,way[pre[i]].v); //流量
ans+=dis[t]*sum;
flow+=sum;
for (i=t;i!=s;i=way[pre[i]].x)
{
way[pre[i]].v-=sum;
way[pre[i]^1].v+=sum;
}
}
printf("%d %d
",flow,ans);
return;
}
int main()
{
memset(st,-1,sizeof(st));
n=in();m=in();s=in();t=in();
for (int i=1;i<=m;i++)
{
int u,w,z,c;
u=in();w=in();z=in();c=in();
add(u,w,z,c);
}
doit();
return 0;
}