最大流
void addedge(int x,int y,int v)
{
tot++;
edge[tot]=EDGE(y, t[x], v, tot+1);
t[x]=tot;
tot++;
edge[tot]=EDGE(x, t[y], 0, tot-1);
t[y]=tot;
}
int bfs()
{
for(int i=s;i<=e;i++) vist[i]=0;
que[1]=s; vist[s]=1;
int head=0,tail=1;
while(head<tail)
{
head++;
int x=que[head];
for(int p=t[x];p>0;p=edge[p].nxt)
{
int y=edge[p].to;
if(edge[p].v>0&&!vist[y])
{
vist[y]=vist[x]+1;
que[++tail]=y;
}
}
}
return vist[e];
}
int dfs(int x,int f)
{
if(x==e||!f) return f;
int sumf=0;
for(int p=t[x];p>0;p=edge[p].nxt)
{
int y=edge[p].to;
if(vist[y]==vist[x]+1&&edge[p].v>0)
{
int flow=dfs(y,min(f,edge[p].v));
edge[p].v-=flow;
edge[edge[p].re].v+=flow;
f-=flow;
sumf+=flow;
if(!f) break;
}
}
return sumf;
}
int dinic()
{
int ans=0;
while(bfs()) { ans+=dfs(s,inf); }
return ans;
}
费用流
struct EDGE{
int to, nxt, re, v, u;
LL c;
EDGE(){}
EDGE(int a, int b, int d, int e, int f, LL g)
{ to = a; nxt = b; v = d; u = e; re = f; c = g;}
}edge[M];
int t[N], pre[N], pree[N], vist[N];
LL dist[N];
int tot;
LL cost;
queue<int>que;
void memclear()
{
tot = 0;
memset(t, 0, sizeof(t));
}
void addedge(int x,int y,int v, LL c)
{
tot++;
edge[tot]=EDGE(y, t[x], v, 0, tot+1, c);
t[x]=tot;
tot++;
edge[tot]=EDGE(x, t[y], 0, 0, tot-1, -c);
t[y]=tot;
}
int spfa(int S, int E)
{
for(int i=1;i<=E;i++) dist[i]=inf;
dist[0]=0; que.push(0); vist[0]=1;
while(que.empty() == 0)
{
int x=que.front();
que.pop();
for(int p=t[x];p>0;p=edge[p].nxt)
{
int y=edge[p].to;
if(edge[p].v>edge[p].u&&dist[y]>dist[x]+edge[p].c)
{
dist[y]=dist[x]+edge[p].c;
pree[y]=p; pre[y]=x;
if(vist[y]==0)
{
vist[y]=1;
que.push(y);
}
}
}
vist[x]=0;
}
return (dist[E]<inf);
}
void update(int S, int E)
{
LL maxa=1e9 + 7;
int x=E;
while(x != S)
{
int p=pree[x];
maxa=min(maxa,(LL)edge[p].v-edge[p].u);
x=pre[x];
}
x=E;
while(x != S)
{
int p=pree[x];
cost+=maxa*edge[p].c;
edge[p].u+=maxa; edge[edge[p].re].u-=maxa;
x=pre[x];
}
}
void solve(int S, int E, int n)
{
cost = 0;
for(int i = 1;i <= n; i++)
{
spfa(S, E);
update(S, E);
cout<<cost;
if(i != n)
cout<<" ";
}
cout<<endl;
}
最大费用可行流
//注意可能需要判环的情况
struct EDGE{
int to, nxt, re, v, u;
LL c;
EDGE(int a = 0, int b = 0, int d = 0, int e = 0, int f = 0, LL g = 0)
{ to = a; nxt = b; v = d; u = e; re = f; c = g;}
}edge[M];
int t[N], pre[N], pree[N], vist[N];
LL dist[N];
int tot;
LL cost;
queue<int>que;
void memclear(int S, int E)
{
for(int i = S; i <= E; i++)
t[i] = 0;
tot = 0; cost = 0;
}
void addedge(int x,int y,int v, LL c)
{
tot++;
edge[tot]=EDGE(y, t[x], v, 0, tot+1, c);
t[x]=tot;
tot++;
edge[tot]=EDGE(x, t[y], 0, 0, tot-1, -c);
t[y]=tot;
}
int spfa(int S, int E)
{
for(int i = 1;i <= E;i++) dist[i] = inf;
dist[S] = 0; que.push(0); vist[0] = 1;
while(que.empty() == 0)
{
int x = que.front();
que.pop();
for(int p = t[x]; p > 0; p = edge[p].nxt)
{
int y = edge[p].to;
if(edge[p].v > edge[p].u && dist[y] > dist[x] + edge[p].c)
{
dist[y] = dist[x] + edge[p].c;
pree[y] = p; pre[y] = x;
if(vist[y] == 0)
{
vist[y] = 1;
que.push(y);
}
}
}
vist[x] = 0;
}
return (dist[E] <= 0);
}
void update(int S, int E)
{
LL maxa = inf;
int x = E;
while(x != S)
{
int p = pree[x];
maxa = min(maxa,(LL)edge[p].v-edge[p].u);
x = pre[x];
}
x = E;
while(x != S)
{
int p = pree[x];
cost += maxa*edge[p].c;
edge[p].u += maxa; edge[edge[p].re].u -= maxa;
x = pre[x];
}
}
int main()
{
int n, m;
while(scanf("%d%d", &n, &m) != EOF)
{
int S = 0;
int E = n + 1;
memclear(S, E);
for(int i = 1; i <= n; i++)
{
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
addedge(S, i, b, a);
addedge(i, E, d, -c);
}
for(int i = 1; i <= m; i++)
{
int x, y, v;
scanf("%d%d%d", &x, &y, &v);
addedge(x, y, inf, v);
addedge(y, x, inf, v);
}
while(spfa(S, E))
update(S, E);
cout<<-cost<<endl;
}
return 0;
}