#include using namespace std; using ll = long long; using uint = unsigned int; #define rep(i,n) for(int i=0;i=0;i--) #define per1(i,n) for(int i=int(n);i>0;i--) #define all(c) c.begin(),c.end() #define si(x) int(x.size()) #define pb emplace_back #define fs first #define sc second template using V = vector; template using VV = vector>; template void chmax(T& x, U y){if(x void chmin(T& x, U y){if(y void mkuni(V& v){sort(all(v));v.erase(unique(all(v)),v.end());} template ostream& operator<<(ostream& o,const pair &p){ return o<<"("< ostream& operator<<(ostream& o,const vector &vc){ o<<"{"; for(const T& v:vc) o< G; V h; V dist; V prevv,preve; MinCostFlow(int N_):N(N_){ G.resize(N); h.resize(N); dist.resize(N); prevv.resize(N); preve.resize(N); } void add_edge(int from, int to, C cap, D cost){ show(cap); show(cost); edge e1(to,cap,cost,(int)G[to].size()); edge e2(from,0,-cost,(int)G[from].size()); G[from].push_back(e1); G[to].push_back(e2); } D min_cost_flow(int s, int t, C f){ D res = 0; h = V(N); while(f > 0){ using P = pair; priority_queue< P,vector

,greater

> que; dist = V(N,inf); dist[s] = 0; que.push(P(0,s)); while(!que.empty()){ P p = que.top(); que.pop(); int v = p.second; if(dist[v] < p.first) continue; for(int i=0;i<(int)G[v].size();i++){ edge &e = G[v][i]; if(e.cap>0 && dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){ dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; prevv[e.to]=v; preve[e.to]=i; que.push(P(dist[e.to],e.to)); } } } if(dist[t]==inf) return -1; rep(v,N) h[v]+=dist[v]; C d = f; for(int v=t;v!=s;v=prevv[v]){ chmin(d,G[prevv[v]][preve[v]].cap); } f -= d; res += d*h[t]; for(int v=t;v!=s;v=prevv[v]){ edge &e=G[prevv[v]][preve[v]]; e.cap-=d; G[v][e.rev].cap+=d; } } return res; } /* 流量を横軸に、コストを縦軸に取ったときのグラフ 各線分の (dx,dy/dx) の vector を返す CF621 G */ V> min_cost_flow_slopes(int s, int t){ // {(x,tan)} V> res; h = V(N); while(true){ using P = pair; priority_queue< P,vector

,greater

> que; dist = V(N,inf); dist[s] = 0; que.push(P(0,s)); while(!que.empty()){ P p = que.top(); que.pop(); int v = p.second; if(dist[v] < p.first) continue; for(int i=0;i<(int)G[v].size();i++){ edge &e = G[v][i]; if(e.cap>0 && dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){ dist[e.to]=dist[v]+e.cost+h[v]-h[e.to]; prevv[e.to]=v; preve[e.to]=i; que.push(P(dist[e.to],e.to)); } } } if(dist[t]==inf) break; rep(v,N) h[v]+=dist[v]; C f = inf; for(int v=t;v!=s;v=prevv[v]){ chmin(f,G[prevv[v]][preve[v]].cap); } res.pb(f,h[t]); // x, tan for(int v=t;v!=s;v=prevv[v]){ edge &e=G[prevv[v]][preve[v]]; e.cap-=f; G[v][e.rev].cap+=f; } } return res; } }; int main(){ cin.tie(0); ios::sync_with_stdio(false); //DON'T USE scanf/printf/puts !! cout << fixed << setprecision(20); int N,M; cin >> N >> M; MinCostFlow MCF(N); rep(i,M){ int x,y,c,d; cin >> x >> y >> c >> d; x--,y--; MCF.add_edge(x,y,1,c); MCF.add_edge(y,x,1,c); MCF.add_edge(x,y,1,d); MCF.add_edge(y,x,1,d); } cout << MCF.min_cost_flow(0,N-1,2) << endl; }