Cod sursa(job #2035130)

Utilizator tifui.alexandruTifui Ioan Alexandru tifui.alexandru Data 8 octombrie 2017 22:42:40
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.63 kb
#include <bits/stdc++.h>
#define Nmax 351
#define tip pair <int,int>
#define SIZE 375030
using namespace std;
list <int> G[Nmax];
int cap[Nmax][Nmax];
int cost[Nmax][Nmax];
int c_bf[Nmax];
bitset <Nmax> inq;
int dist[Nmax];
int real_d[Nmax];
int t[Nmax];
queue <int> q;
int n,s,d,ans,minn;
priority_queue <tip, vector <tip>, greater <tip> > pq;
class myifstream
{
    public:
        myifstream();
        myifstream(const char *input_name)
        {
            input=fopen(input_name,"r");
            cursor=0;
            fread(buffer,SIZE,1,input);
        }
        inline myifstream &operator >> (int &x)
        {
            while((buffer[cursor]<'0' or buffer[cursor]>'9') and buffer[cursor]!='-')
                    advance();
            sgn=1;
            if(buffer[cursor]=='-')
            {
                sgn=-1;
                advance();
            }
            x=0;
            while(buffer[cursor]>='0' and buffer[cursor]<='9')
            {
                x=x*10+buffer[cursor]-'0';
                advance();
            }
            x*=sgn;
            return *this;
        }
    private :
        FILE *input;
        char buffer[SIZE];
        long cursor;
        int sgn;
        void advance()
        {
            ++cursor;
            if(cursor==SIZE)
            {
                cursor=0;
                fread(buffer,SIZE,1,input);
            }
        }
};
bool Dijkstra()
{
    memset(dist,0x3f,sizeof(dist));
    dist[s]=0;
    real_d[s]==0;
    pq.push({dist[s],s});
    int x,dij_cst,new_dist;
    list <int> :: iterator it;
    while(!pq.empty())
    {
        x=pq.top().second;
        dij_cst=pq.top().first;
        pq.pop();
        if(dist[x]==dij_cst)
        for(it=G[x].begin();it!=G[x].end();it++)
        if(cap[x][*it])
        {
            new_dist=dist[x]+cost[x][*it]+c_bf[x]-c_bf[*it];
            if(new_dist<dist[*it])
            {
                dist[*it]=new_dist;
                real_d[*it]=real_d[x]+cost[x][*it];
                t[*it]=x;
                pq.push({dist[*it],*it});
            }
        }
    }
    memcpy(c_bf,real_d,sizeof(dist));
    if(dist[d]==0x3f3f3f3f) return false;
    minn=0x3f3f3f3f;
    x=d;
    while(x!=s)
    {
        if(cap[t[x]][x]<minn)
            minn=cap[t[x]][x];
        x=t[x];
    }
    ans+=(minn*real_d[d]);
    x=d;
    while(x!=s)
    {
        cap[t[x]][x]-=minn;
        cap[x][t[x]]+=minn;
        x=t[x];
    }
    return true;
}
void BF()
{
    memset(c_bf,0x3f,sizeof(c_bf));
    c_bf[s]=0;
    q.push(s);
    inq[s]=true;
    int x;
    list <int> :: iterator it;
    while(!q.empty())
    {
        x=q.front();
        q.pop();
        inq[x]=false;
        for(it=G[x].begin();it!=G[x].end();it++)
            if(cap[x][*it] and c_bf[*it]>c_bf[x]+cost[x][*it])
            {
                c_bf[*it]=c_bf[x]+cost[x][*it];
                if(!inq[*it])
                {
                    q.push(*it);
                    inq[*it]=true;
                }
            }
    }
}
myifstream f("fmcm.in");
ofstream g("fmcm.out");
int main()
{
   // freopen("fmcm.in","rt",stdin);
   // freopen("fmcm.out","wt",stdout);
    int m,i,j,z,cst,k;
    //scanf("%d%d%d%d",&n,&m,&s,&d);
    f>>n>>m>>s>>d;
    for(k=1;k<=m;k++)
    {
        //scanf("%d%d%d%d",&i,&j,&z,&cst);
        f>>i>>j>>z>>cst;
        G[i].push_back(j);
        G[j].push_back(i);
        cap[i][j]=z;
        cost[i][j]=cst;
        cost[j][i]=-cst;
    }
    BF();
    ans=0;
    while(Dijkstra());
    //printf("%d",ans);
    g<<ans;


    return 0;
}