CSPRO

201412-5 货物调度

//201412-5 货物调度
//点从1开存,1..N
#include <cstdio>
#include<cstring>
#include<algorithm>
#define V 720
#define E 160000
#define MIN(a,b) ((a)<(b)?(a):(b))
#define OPPOSITE(x) (((x)&1)?((x)+1):((x)-1))
const int inf=0x3f3f3f3f;
#define fr(i,x,y) for(int i=x;i<=y;i++)
#define ms(x,y) memset(x,y,sizeof(x))
using namespace std;
int N,S,T;
int begin[V],end[E],next[E],c[E],
    cost[E],d[V],cur[V];
bool hash[V];
int Count=0;
int aug(int u,int f){
    if (u == T) return f;
    hash[u] = true;
    for (int now = cur[u]; now; now = next[now])
        if (c[now]&&!hash[end[now]]&&d[u] == d[end[now]]+cost[now])
            if (int tmp = aug(end[now],MIN(f,c[now])))
                return c[now] -= tmp,c[now^1] += tmp,cur[u] = now,tmp;
    return 0;
}
bool modlabel(){
    int tmp = inf;
    for (int i = 1; i<=N; i++)
        if (hash[i])
            for (int now = begin[i]; now; now = next[now])
                if (c[now]&&!hash[end[now]])
                    tmp = MIN(tmp,d[end[now]]+cost[now]-d[i]);
    if (tmp == inf)return true;
    for (int i = 1; i<=N; i++)
        if (hash[i])
            hash[i] = false,d[i] += tmp;
    return false;
}
int CostFlow(){
    int costflow = 0,tmp;
    while (true){
        for (int i = 1; i<=N; i++)
            cur[i] = begin[i];
        while (tmp = aug(S,inf)){
            costflow += tmp*d[S];
            ms(hash,0);
        }
        if (modlabel())
            break;
    }
    return costflow;
}
inline void AddEdge(int a,int b,int flow, int v){
    next[Count] = begin[a]; begin[a] = Count; end[Count] = b; c[Count] = flow; cost[Count] = v;Count++;
    next[Count] = begin[b]; begin[b] = Count; end[Count] = a; c[Count] = 0; cost[Count] = -v;Count++;
}


int n,m,id[7][105];
int dist[105][105];
int aa[105][7],bb[105][7],ww[105],costt[105];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        {
            fr(j,0,6)scanf("%d",&aa[i][j]);
            fr(j,0,6)scanf("%d",&bb[i][j]);
            scanf("%d%d",&ww[i],&costt[i]);
        }
    ms(dist,0x3f);
    fr(i,1,n) dist[i][i]=0;
    int x,y,z;
    fr(i,1,m)
    {
        scanf("%d%d%d",&x,&y,&z);
        dist[x][y]=min(dist[x][y],z);
        dist[y][x]=min(dist[y][x],z);
    }
    fr(k,1,n)fr(i,1,n)fr(j,1,n)dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
    int idd=1;
    fr(j,0,6)fr(i,1,n) id[j][i]=++idd;
    S=1;T=++idd;N=T;
    ms(begin,0);Count=2;
    fr(j,0,6)fr(i1,1,n)fr(i2,1,n)    AddEdge(id[j][i1],id[j][i2],  inf,dist[i1][i2]);
    fr(j,0,6) fr(i,1,n)               AddEdge(S,id[j][i],           aa[i][j],0);
    fr(j,0,6) fr(i,1,n)               AddEdge(id[j][i],T,           bb[i][j],0);
    fr(j,0,5)fr(i,1,n)               AddEdge(id[j][i],id[j+1][i],ww[i],costt[i]);
    fr(j,6,6)fr(i,1,n)               AddEdge(id[j][i],id[0][i],ww[i],costt[i]);
    printf("%d\n",CostFlow());
}
/*
1 0
0 0 0 0 5 0 0
0 0 0 0 0 5 0
5 4
*/



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值