网络流之最大流
Dinic+SPFA
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100010
#define M 500010
#define maxn 2147483647
int last[N],len=1;
int dis[N],q[N],p[N],ans=0,cur[N];
struct
{
int c,w,to,next;
}a[M*2];
int n,m;
void add(int x,int y,int c,int w)
{
a[++len].to=y;
a[len].next=last[x];
a[len].c=c,a[len].w=w;
last[x]=len;
}
int SPFA()
{
for(int i=1;i<=n;i++) dis[i]=maxn;
memset(p,0,sizeof(p));
q[1]=p[1]=1,dis[1]=0;
int l=0,r=1;
while(l!=r)
{
l=l%n+1;
int k=q[l];
for(int i=last[k];i;i=a[i].next)
{
int x=a[i].to;
if(dis[k]+a[i].w<dis[x]&&a[i].c)
{
dis[x]=dis[k]+a[i].w;
if(!p[x])
{
p[x]=1;
r=r%n+1;
q[r]=x;
}
}
}
p[k]=0;
}
return dis[n]<maxn;
}
int dfs(int k,int flow)
{
if(k==n) return flow;
int have=0;
p[k]=1;
for(int i=last[k];i;i=a[i].next)
{
int x=a[i].to;
if(!p[x]&&dis[k]+a[i].w==dis[x]&&a[i].c)
{
int t=min(flow-have,a[i].c);
int now=dfs(x,t);
ans+=now*a[i].w;
have+=now,a[i].c-=now,a[i^1].c+=now;
if(have==flow) break;
}
}
p[k]=0;
return have;
}
int main()
{
int i,x,y,c,w;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&c,&w);
add(x,y,c,w);
add(y,x,0,-w);
}
int sum=0;
while(SPFA())
{
while(1)
{
for(i=1;i<=n;i++) cur[i]=last[i];
int t=dfs(1,maxn);
if(t) sum+=t; else break;
}
}
printf("%d %d",sum,ans);
return 0;
}