Pagini recente » Cod sursa (job #1442377) | Cod sursa (job #1875741) | Cod sursa (job #791179) | Cod sursa (job #1775049) | Cod sursa (job #2960375)
#include<fstream>
#include<vector>
#include<queue>
#include<bitset>
#include<cstring>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
const int NMAX = 351;
const int INF = 1e9;
int cap[NMAX][NMAX],flow[NMAX][NMAX],cost[NMAX][NMAX];
vector<int> vecini[NMAX];
int t[NMAX],n;
bitset<NMAX> inq;
int bf(int s,int d)
{
vector<int> dp(NMAX,INF);
dp[s] = 0; queue<int> q;
q.push(s);
inq.reset(); inq[s] = 1;
memset(t,0,sizeof(t));
while(!q.empty())
{
int v = q.front(); q.pop();
inq[v] = 0;
for(auto it : vecini[v])
{
if(!(cap[v][it] - flow[v][it]))///daca nu am capacitate reziduala,nu pot folosi muchia
continue;
if(dp[v] + cost[v][it] < dp[it])
{
t[it] = v;
dp[it] = dp[v] + cost[v][it];
if(!inq[it])
{
q.push(it);
inq[it] = 1;
}
}
}
}
if(dp[d] == INF)///daca nu ajung la destintatie inseamna ca nu exista drum de augmentare
return 0;
int r = INF;
while(d != s)
{
r = min(r,cap[t[d]][d] - flow[t[d]][d]);
d = t[d];
}
return r;
}
void wannabe(int s,int d)
{
///vreau un drum de cost minim folosind doar muchii de augmentare
int primesc = bf(s,d);
long long ans = 0;
while(primesc > 0)
{
int nod = d;
while(nod != s)
{
flow[t[nod]][nod] += primesc;
flow[nod][t[nod]] -= primesc;
ans += 1LL * primesc * cost[t[nod]][nod];
nod = t[nod];
}
primesc = bf(s,d);
}
fout << ans;
exit(0);
}
int main()
{
int a,b,s,d,c,m,z; fin >> n >> m >> s >> d;
for(int i = 1; i <= m ; i++)
{
fin >> a >> b >> c >> z;
vecini[a].emplace_back(b);
cap[a][b] = c;
cost[a][b] = z;
cost[b][a] = -z;
}
wannabe(s,d);
}