BZOJ3931 CQOI2015 网络吞吐量 最短路+网络流

题意:求1到N的所有最短路方案上的最大流,阈值在每个点上

题解:呵呵哒

#include <queue>
#include <vector>
#include <functional>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3fll

const int MAXN=1000+2;
const int MAXM=400000+2;
struct HASH{
    int u;
    ll w;
    HASH *next;
    HASH(){}
    HASH(int _u,ll _w,HASH *_next):u(_u),w(_w),next(_next){}
}*table[MAXN],mem[MAXM];
struct EDGE{
    int u;
    ll c;
    EDGE(){}
    EDGE(int _u,ll _c):u(_u),c(_c){}
    bool friend operator<(EDGE a,EDGE b){ return a.c>b.c;}
}e[MAXM];
int N,M,cur[MAXN],cnt;
ll d[MAXN];
bool flag[MAXN];
queue<int> q;
vector<int> tab[MAXN];
priority_queue<EDGE> pq;

void Insert1(int u,int v,ll w){
    for(HASH *p=table[u];p;p=p->next)
        if(p->u==v){
            p->w=min(w,p->w);
            return;
        }

    table[u]=&(mem[cnt++]=HASH(v,w,table[u]));
}

void Insert2(int u,int v,ll c){
    tab[u].push_back(cnt),e[cnt++]=EDGE(v,c);
    tab[v].push_back(cnt),e[cnt++]=EDGE(u,0);
}

void Dijkstra(){
    for(int i=1;i<=N;i++) d[i]=INF;
    d[1]=0,pq.push(EDGE(1,0)),flag[1]=1;

    int x;
    while(!pq.empty()){
        x=pq.top().u,pq.pop();
        for(HASH *p=table[x];p;p=p->next)
            if(d[p->u]>d[x]+p->w){
                d[p->u]=d[x]+p->w;
                if(!flag[p->u]) pq.push(EDGE(p->u,d[p->u]));
            }
        flag[x]=0;
    }
}

bool BFS(int s,int t){
    memset(d,-1,sizeof(d));
    d[s]=0,q.push(s);

    int x;
    while(!q.empty()){
        x=q.front(),q.pop();
        for(int i=0;i<tab[x].size();i++)
            if(d[e[tab[x][i]].u]==-1 && e[tab[x][i]].c)
                d[e[tab[x][i]].u]=d[x]+1,q.push(e[tab[x][i]].u);
    }
    return d[t]>0;
}

ll DFS(int x,ll f,int t){
    if(x==t) return f;

    ll flow,used=0;
    for(int i=cur[x];i<tab[x].size();i++)
        if(e[tab[x][i]].c && d[e[tab[x][i]].u]==d[x]+1){
            flow=DFS(e[tab[x][i]].u,min(f-used,e[tab[x][i]].c),t);
            e[tab[x][i]].c-=flow,e[tab[x][i]^1].c+=flow,used+=flow;
            if(e[tab[x][i]].c) cur[x]=i;
            if(f==used) return f;
        }

    if(!used) d[x]=-1;
    return used;
}

ll Dinic(int s,int t){
    ll ret=0;
    while(BFS(s,t)){
        memset(cur,0,sizeof(cur));
        ret+=DFS(s,INF,t);
    }
    return ret;
}

int main(){
    scanf("%d %d",&N,&M);
    for(int i=1,u,v,w;i<=M;i++){
        scanf("%d %d %d",&u,&v,&w);
        Insert1(u,v,w),Insert1(v,u,w);
    }
    Dijkstra();

    cnt=0;
    for(int i=1,c;i<=N;i++){
        scanf("%d",&c);
        Insert2(i,N+i,c);
    }
    for(int i=1;i<=N;i++)
        for(HASH *p=table[i];p;p=p->next)
            if(d[p->u]==d[i]+p->w) Insert2(N+i,p->u,INF);

    printf("%lld\n",Dinic(N+1,N));

    return 0;
}
View Code

 

posted @ 2017-02-28 22:41  WDZRMPCBIT  阅读(144)  评论(0编辑  收藏  举报