hdu 3667

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define M 2000020
#define N 550
#define FOR(i,n) for(int i=0;i<n;i++)
#define INF 0x7fffffff

using namespace std;

struct Node
{
    int cost;
    int flow;
    int cap;
    int u;
    int v;
    int next;
}edge[M];
int head[N];

void add_edge( int u, int v, int cost, int cap, int &num , int n )
{
    edge[num].u = u;
    edge[num].v = v;
    edge[num].cap = cap;
    edge[num].cost = cost;
    edge[num].flow = 0;
    edge[num].next = head[u];
    head[u] = num ++;

    edge[num].u = v;
    edge[num].cap = 0;
    edge[num].v = u;
    edge[num].cost = -cost;
    edge[num].flow = 0;
    edge[num].next = head[v];
    head[v] = num ++;
}

void get_map( int n, int m, int k )
{
    int u,v, a, w, num = 0;
    memset(head,-1,sizeof(head));
    FOR(i,m) {
        scanf("%d%d%d%d",&u,&v,&w,&a);
        FOR(i,a) add_edge(u,v,(i*2+1)*w, 1, num, n );
    }
}

int dis[N], pre[N],que[N];
char mark[N];

int spfa( int s, int t, int n )
{
    int front = 0, rear = 0;
    FOR(i,n+1) {
        dis[i]=INF;
        mark[i] = 0;
        pre[i] = -1;
    }
    mark[s] = 1;
    dis[s]=0;
    que[rear++] =s;
    while( front!=rear )
    {
        int u = que[front++];
        if( front == N ) front = 0;
        mark[u] = 0;
        for( int p = head[u]; p!=-1; p = edge[p].next )
        {
            int v = edge[p].v;
            if( edge[p].cap>edge[p].flow && dis[v]-dis[u]>edge[p].cost )
            {
                dis[v] = dis[u] + edge[p].cost;
                pre[v] = p;
                if( !mark[v] )
                {
                    mark[v] = 1;
                    que[rear++] = v;
                    if( rear == N ) rear = 0;
                }
            }
        }
    }
    return dis[t];
}

int mincost( int s, int t, int n, int k )
{
    int min_cost = 0, i ;
    for( i = 0; spfa(s,t,n)!=INF && i < k; i++ )
    {
        int mx = INF;
        for( int u = pre[t]; u!=-1; u = pre[ edge[u].u ] )
        if( mx > edge[u].cap-edge[u].flow ) mx = edge[u].cap-edge[u].flow;
        for( int u = pre[t]; u!=-1; u = pre[edge[u].u] )
        {
            min_cost += edge[u].cost*mx;
            edge[u].flow +=mx;
            edge[u^1].flow-=mx;
        }
    }
    if( i < k ) return -1;
    else return min_cost;
}

int main()
{
    //freopen("in.txt","r",stdin);
    for(int n,m,k; scanf("%d%d%d",&n,&m,&k) != EOF; )
    {
        get_map(n,m,k);
        printf("%d\n",mincost(1,n,n,k));
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章