Pagini recente » Cod sursa (job #2073925) | Clasament dasdsad | Cod sursa (job #2727540) | Istoria paginii utilizator/lungueduard | Cod sursa (job #744975)
Cod sursa(job #744975)
#include<fstream>
#include<vector>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,S,D;
int C[355][355],F[355][355],cost[355][355],Dist[355],viz[355],sum;
vector <int> G[355];
long long sol;
int H[355],poz[355],size;
inline int Min(int a,int b)
{
if(a<b)
return a;
return b;
}
inline void Swap(int &a,int &b)
{
if(a==b)
return;
a^=b^=a^=b;
}
inline void Citire()
{
int i,x,y,cap,c,ns,poz,semn;
char s[50];
ifstream fin("fmcm.in");
//fin>>n>>m>>S>>D;
fin.getline(s,50);
ns=strlen(s);
poz=0;
while(s[poz]!=' ')
{
n=n*10+s[poz]-'0';
poz++;
}
poz++;
while(s[poz]!=' ')
{
m=m*10+s[poz]-'0';
poz++;
}
poz++;
while(s[poz]!=' ')
{
S=S*10+s[poz]-'0';
poz++;
}
poz++;
while(poz<ns)
{
D=D*10+s[poz]-'0';
poz++;
}
//
for(i=1;i<=m;i++)
{
//fin>>x>>y>>cap>>c;
fin.getline(s,50);
ns=strlen(s);
poz=0;
x=0;
if(s[poz]=='-')
{
semn=-1;
poz++;
}
else
semn=1;
while(s[poz]!=' ')
{
x=x*10+s[poz]-'0';
poz++;
}
x*=semn;
poz++;
y=0;
if(s[poz]=='-')
{
semn=-1;
poz++;
}
else
semn=1;
while(s[poz]!=' ')
{
y=y*10+s[poz]-'0';
poz++;
}
y*=semn;
poz++;
cap=0;
if(s[poz]=='-')
{
semn=-1;
poz++;
}
else
semn=1;
while(s[poz]!=' ')
{
cap=cap*10+s[poz]-'0';
poz++;
}
cap*=semn;
poz++;
c=0;
if(s[poz]=='-')
{
semn=-1;
poz++;
}
else
semn=1;
while(poz<ns)
{
c=c*10+s[poz]-'0';
poz++;
}
c*=semn;
//
G[x].push_back(y);
G[y].push_back(x);
C[x][y]=cap;
cost[x][y]=c;
cost[y][x]=-c;
}
fin.close();
}
inline void Bellman_Ford()
{
queue <int> Q;
vector <int>::iterator it;
int i,x;
for(i=1;i<=n;i++)
Dist[i]=2000000000;
Dist[S]=0;
Q.push(S);
while(!Q.empty())
{
x=Q.front();
Q.pop();
for(it=G[x].begin();it!=G[x].end();it++)
{
if(C[x][*it]>0 && Dist[*it]>Dist[x]+cost[x][*it])
{
Dist[*it]=Dist[x]+cost[x][*it];
Q.push(*it);
}
}
}
sum=Dist[D];
}
inline void Up_Heap(int nod)
{
int tata=nod/2;
while(tata>0 && Dist[H[nod]]<Dist[H[tata]])
{
Swap(H[nod],H[tata]);
poz[H[nod]]=nod;
poz[H[tata]]=tata;
nod=tata;
tata=nod/2;
}
}
inline void Down_Heap(int nod)
{
int tata=0;
while(nod!=tata)
{
tata=nod;
if(2*tata<=size && Dist[H[nod]]>Dist[H[2*tata]])
nod=2*tata;
if(2*tata+1<=size && Dist[H[nod]]>Dist[H[2*tata+1]])
nod=2*tata+1;
Swap(H[nod],H[tata]);
poz[H[nod]]=nod;
poz[H[tata]]=tata;
}
}
inline bool Dijkstra()
{
int i,x;
vector <int>::iterator it;
for(i=1;i<=n;i++)
{
if(Dist[i]==2000000000)
continue;
for(it=G[i].begin();it!=G[i].end();it++)
{
if(Dist[*it]==2000000000)
continue;
cost[i][*it]+=Dist[i]-Dist[*it];
}
}
for(i=1;i<=n;i++)
{
Dist[i]=2000000000;
viz[i]=0;
H[i]=i;
poz[i]=i;
}
Dist[S]=0;
H[1]=S; H[S]=1;
poz[1]=S; poz[S]=1;
size=n;
while(size>1 && Dist[H[1]]!=2000000000)
{
x=H[1];
H[1]=H[size]; poz[H[1]]=1;
size--;
if(size>1)
Down_Heap(1);
for(it=G[x].begin();it!=G[x].end();it++)
{
if(C[x][*it]>F[x][*it] && Dist[*it]>Dist[x]+cost[x][*it])
{
Dist[*it]=Dist[x]+cost[x][*it];
viz[*it]=x;
Up_Heap(poz[*it]);
}
}
}
if(Dist[D]==2000000000)
return false;
return true;
}
inline void Max_Flow()
{
int x,val;
while(1)
{
if(Dijkstra()==false)
return;
val=2000000000;
x=D;
while(viz[x])
{
val=Min(val,C[viz[x]][x]-F[viz[x]][x]);
x=viz[x];
}
x=D;
while(viz[x])
{
F[viz[x]][x]+=val;
F[x][viz[x]]-=val;
x=viz[x];
}
sum+=Dist[D];
sol+=(long long)(val*sum);
}
}
inline void Afisare()
{
ofstream fout("fmcm.out");
fout<<sol<<"\n";
fout.close();
}
int main()
{
Citire();
Bellman_Ford();
Max_Flow();
Afisare();
return 0;
}