zoukankan      html  css  js  c++  java
  • BZOJ 3931: [CQOI2015]网络吞吐量 Dijkstra+最大流

    这个没啥难的. 

    只保留可以转移最短路的边,然后拆点跑一个最大流即可.   

    #include <bits/stdc++.h>   
    #define N 1004  
    #define M 250004          
    #define ll long long  
    #define inf 200000000001 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;           
    int s,t,tot,n,m,eds; 
    int vis[N],current[N],id[N][2],hd[N],to[M],nex[M],val[M],cc[N],U[M],V[M],VAL[M];                     
    void add(int u,int v,int c) 
    {
        nex[++eds]=hd[u],hd[u]=eds,to[eds]=v,val[eds]=c;   
    }
    struct Dijkstra
    {     
        ll d[N];
        int done[N];         
        struct Node 
        {
            int u; 
            long long dis; 
            Node(int u=0,ll dis=0):u(u),dis(dis){}      
            bool operator<(Node b) const 
            {
                return b.dis<dis; 
            }
        }; 
        priority_queue<Node>q;     
        void dijkstra(int aa) 
        {
            memset(d,0x3f,sizeof(d));       
            for(d[aa]=0,q.push(Node(aa,0));!q.empty();) 
            {
                Node e=q.top();q.pop(); 
                int u=e.u; 
                if(done[u]) continue;      
                done[u]=1;
                for(int i=hd[u];i;i=nex[i]) 
                { 
                    int v=to[i]; 
                    if(d[v]>d[u]+val[i]) 
                    {
                        d[v]=d[u]+val[i]; 
                        q.push(Node(v, d[v]));    
                    }
                }
            }
        }    
    }S,T; 
    int d[M];   
    struct Edge 
    {
        ll cap; 
        int u,v;    
        Edge(int u=0,int v=0,ll cap=0):u(u),v(v),cap(cap){}   
    };          
    queue<int>q;   
    vector<Edge>edges;   
    vector<int>G[N];    
    void addedge(int u,int v,ll c) 
    {
        edges.push_back(Edge(u,v,c)); 
        edges.push_back(Edge(v,u,0));    
        int p=edges.size();   
        G[u].push_back(p-2);   
        G[v].push_back(p-1);    
    }
    int BFS() 
    {
        memset(vis,0,sizeof(vis)); 
        d[s]=0,q.push(s),vis[s]=1;   
        for(;!q.empty();) 
        {     
            int u=q.front(); q.pop();   
            for(int i=0;i<G[u].size();++i) 
            {
                Edge e=edges[G[u][i]];   
                if(e.cap>0&&!vis[e.v]) 
                {
                    vis[e.v]=1;    
                    d[e.v]=d[u]+1;   
                    q.push(e.v);      
                }
            }
        }    
        return vis[t];    
    }
    ll dfs(int x,ll cur) 
    { 
        if(x==t) return cur;     
        ll f,flow=0;    
        for(int i=0;i<G[x].size();++i) 
        {
            Edge e=edges[G[x][i]];                          
            if(e.cap>0 && d[e.v]==d[x]+1)     
            {
                f=dfs(e.v,min(cur,1ll*e.cap));    
                if(f) flow+=f,cur-=f,edges[G[x][i]].cap-=f,edges[G[x][i]^1].cap+=f;          
            } 
            if(!cur) break; 
        } 
        return flow;    
    }
    ll maxflow() 
    {
        ll flow=0; 
        for(;BFS();) flow+=dfs(s,inf);  
        return flow;   
    }
    int main() 
    {  
        int i,j,k; 
        // setIO("input");       
        scanf("%d%d",&n,&m);  
        for(i=1;i<=n;++i) id[i][0]=++tot, id[i][1]=++tot;     
        for(i=1;i<=m;++i) 
        {
            int a,b,c; 
            scanf("%d%d%d",&a,&b,&c), add(a,b,c),add(b,a,c); 
            U[i]=a,V[i]=b,VAL[i]=c;              
        }     
        for(i=1;i<=n;++i) scanf("%d",&cc[i]);   
        S.dijkstra(1);           
        T.dijkstra(n);         
        addedge(id[1][0],id[1][1],inf);  
        addedge(id[n][0],id[n][1],inf);    
        for(i=2;i<n;++i) 
        {
            addedge(id[i][0],id[i][1],cc[i]);     
        }
        for(i=1;i<=m;++i) 
        {   
            int a=U[i],b=V[i];
            if(S.d[a]+T.d[b]+VAL[i]==S.d[n]) 
            {
                addedge(id[a][1],id[b][0],inf);                
            }   
            swap(a,b);    
            if(S.d[a]+T.d[b]+VAL[i]==S.d[n]) 
            {
                addedge(id[a][1],id[b][0],inf);                
            } 
        }   
        s=id[1][0],t=id[n][1];  
        printf("%lld
    ",maxflow());  
        return 0; 
    }
    

      

  • 相关阅读:
    第二次会议记录(2021.7.19)
    第一次会议记录(2021.7.8)
    软件工程助教工作总结
    Linux下的常用命令
    GPIO输出——使用固件库点亮LED 宏定义遇到的问题
    STM32 GPIO BRR和BSRR寄存器
    snprintf()函数使用方法
    结构体元素偏移量宏的定义及解析
    函数指针&回调函数Callback
    解析#define NULL ((void *)0)——野指针,空指针和 void*
  • 原文地址:https://www.cnblogs.com/guangheli/p/11550805.html
Copyright © 2011-2022 走看看