BZOJ 3931: [CQOI2015]網絡吞吐量

題目在這裏呀

emm昨天深夜急急地調完這題就睡了,今天補一下題解qaq
這題就是道模板題啦,題意怎麼說的就怎麼建邊,注意需要裂點。
剩下就是一遍網絡流就沒啦ww
這題適合複習一下模板qwq

//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define P pair<int,int>
#define ll long long
#define sec second
#define N 505
#define M 100000+1000
using namespace std;
const ll inf=1e18;
int n,m,head[N+N],cur[N+N],a[M],b[M],d[M],S,T,cnt;
ll dis[N+N];

struct edge{
    int to,next;ll cap;
}e[N+N+M+M];

int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

inline void add_edge(int u,int v,ll val){
    e[++cnt]=(edge){v,head[u],val};head[u]=cnt;
}

void dijkstra()
{
    priority_queue<P,vector<P>,greater<P> >q;
    for(int i=1;i<=n;i++) dis[i]=inf;
    dis[1]=0;q.push(make_pair(0,1));
    while(!q.empty()){
        int now=q.top().sec;q.pop();
        for(int i=head[now];i;i=e[i].next)
            if(dis[e[i].to]>dis[now]+e[i].cap){
                dis[e[i].to]=dis[now]+e[i].cap;
                q.push(make_pair(dis[e[i].to],e[i].to));
            }
    }
}

bool bfs()
{
    queue<int> Q;
    for(int i=0;i<=T;i++) dis[i]=-1;
    Q.push(S);dis[S]=0;
    while(!Q.empty())
    {
        int now=Q.front();Q.pop();
        for(int i=head[now];i;i=e[i].next)
            if(e[i].cap && dis[e[i].to]==-1){
                dis[e[i].to]=dis[now]+1;
                Q.push(e[i].to);
            }
    }
    return dis[T]!=-1;
}

inline ll dfs(int x,ll f)
{
    if(x==T) return f;
    ll w,used=0;
    for(int i=cur[x];i;i=e[i].next)
        if(dis[e[i].to]==dis[x]+1){
            w=f-used;
            w=dfs(e[i].to,min(w,e[i].cap));
            e[i].cap-=w;e[i ^ 1].cap+=w;
            if(e[i].cap) cur[x]=i;
            used+=w;
            if(used==f) return f;
        }
    if(!used) dis[x]=-1;
    return used;
}

ll dinic()
{
    ll ans=0;
    while(bfs()){
        for(int i=1;i<=T;i++) cur[i]=head[i];
        ans+=dfs(S,inf);
    }
    return ans;
}

int main()
{
    n=read();m=read();
    for(int i=1;i<=m;i++){
        a[i]=read();b[i]=read();d[i]=read();
        add_edge(a[i],b[i],d[i]);add_edge(b[i],a[i],d[i]);
    }
    dijkstra();
    memset(head,0,sizeof(head));
    cnt=1;
    for(int i=1;i<=m;i++){
        if(dis[a[i]]+d[i]==dis[b[i]]) add_edge(a[i]+n,b[i],inf),add_edge(b[i],a[i]+n,0);
        if(dis[b[i]]+d[i]==dis[a[i]]) add_edge(b[i]+n,a[i],inf),add_edge(a[i],b[i]+n,0);
    }
    for(int i=1;i<=n;i++){
        int c=read();
        if(i>1 && i<n) add_edge(i,i+n,c);
        else add_edge(i,i+n,inf);
        add_edge(i+n,i,0);
    }
    S=1;T=n+n;
    printf("%lld\n",dinic());
    return 0;
}



/*
7 10
1 2 2
1 5 2
2 4 1
2 3 3
3 7 1
4 5 4
4 3 1
4 6 1
5 6 2
6 7 1
1
100
20
50
20
60
1
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章