[CQOI2015]网络吞吐量 - 最短路 - 网络流

传送门

题解:如题求出最短路网拆点跑网络流即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<climits>
#define INF (LLONG_MAX/3)
#define MAXN 1010
#define MAXM 200010
#define lint long long
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
int n;bool vis[MAXN];lint d[MAXN];
struct node{
    int to,wgt;
    node(int _t,int _w)
    {
        to=_t;
        wgt=_w;
    }
};
vector<node> g[MAXN];
struct heapnode{
    int id;lint dist;
    heapnode(int _i,lint _d)
    {
        id=_i;
        dist=_d;
    }
    bool operator<(const heapnode &hn)const
    {
        return this->dist>hn.dist;
    }
};
priority_queue<heapnode> heap;
struct edges{
    int to,pre;lint resf;
}e[MAXM];
int etop,h[MAXN],cur[MAXN];
inline int add_edge(int u,int v,lint c)
{
    etop++;
    e[etop].to=v;
    e[etop].resf=c;
    e[etop].pre=h[u];
    h[u]=etop;
    return 0;
}
inline int build_edge(int u,int v,lint c)
{
    add_edge(u,v,c),add_edge(v,u,0);return 0;
}
lint dijkstra(int s,int t)
{
    memset(vis,false,sizeof(vis));
    while(!heap.empty()) heap.pop();
    for(int i=1;i<=n;i++) d[i]=INF;
    heap.push(heapnode(s,d[s]=0));
    while(!heap.empty())
    {
        int x=heap.top().id;heap.pop();
        if(vis[x]) continue;vis[x]=true;
        for(int i=0;i<g[x].size();i++)
        {
            int v=g[x][i].to;lint w=g[x][i].wgt;
            if(!vis[v]&&d[v]>d[x]+w)
                heap.push(heapnode(v,d[v]=d[x]+w));
        }
    }
    return d[t];
}
queue<int> q;int lev[MAXN];
inline bool bfs(int s,int t)
{
    memset(vis,false,sizeof(vis));
    while(!q.empty()) q.pop();
    memset(lev,0,sizeof(lev));
    lev[s]=0;q.push(s);vis[s]=true;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=h[x];i;i=e[i].pre)
            if(!vis[e[i].to]&&e[i].resf)
            {
                vis[e[i].to]=true;
                lev[e[i].to]=lev[x]+1;
                q.push(e[i].to);
            }
    }
    return vis[t];
}
inline lint dfs(int s,int t,lint a)
{
    if(s==t||!a) return a;
    lint flow=0,f;
    for(int &i=cur[s];i;i=e[i].pre)
        if(lev[e[i].to]==lev[s]+1&&(f=dfs(e[i].to,t,min(e[i].resf,a)))>0)
        {
            a-=f;flow+=f;e[i].resf-=f;
            e[((i-1)^1)+1].resf+=f;
            if(!a) break;
        }
    return flow;
}
int main()
{
    int m;scanf("%d%d",&n,&m);
    while(m--)
    {
        int u,v,w;scanf("%d%d%d",&u,&v,&w);
        g[u].push_back(node(v,w));
        g[v].push_back(node(u,w));
    }
    for(int i=1;i<=n;i++)
    {
        int c;scanf("%d",&c);
        if(i==1||i==n) build_edge(i,i+n,INF);
        else build_edge(i,i+n,c);
    }
    int s=1,t=n<<1;
    dijkstra(1,n);
    for(int i=1;i<=n;i++)
        for(int j=0;j<g[i].size();j++)
            if(d[i]+g[i][j].wgt==d[g[i][j].to])
                build_edge(i+n,g[i][j].to,INF);
    lint flow=0;
    while(bfs(s,t))
    {
        for(int i=s;i<=t;i++)
            cur[i]=h[i];
        flow+=dfs(s,t,INF);
    }
    printf("%lld\n",flow);return 0;
}



阅读更多

没有更多推荐了,返回首页