zoukankan      html  css  js  c++  java
  • bzoj 3931 [CQOI2015]网络吞吐量(最短路,最大流)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=3931

    【题意】

        只能通过1-n的最短路,求网络最大流

    【思路】

        分别以1,n为起点做最短路,则可以判断一条边是否在最短路上。

        以最短路构建网络,并且将一个点拆成两个中间连c[i]表示结点容量限制。

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     11 using namespace std;
     12 
     13 typedef long long ll;
     14 const int N = 2e3+10;
     15 const int M = 4e5+10;
     16 const int inf = 1e9;
     17 const ll llinf = 1e18;
     18 
     19 ll read() {
     20     char c=getchar();
     21     ll f=1,x=0;
     22     while(!isdigit(c)) {
     23         if(c=='-') f=-1; c=getchar();
     24     }
     25     while(isdigit(c))
     26         x=x*10+c-'0',c=getchar();
     27     return x*f;
     28 }
     29 
     30 struct DEdge {
     31     int u,v; ll cap,flow;
     32 };
     33 struct Dinic {
     34     int n,m,s,t;
     35     int d[N],cur[N],vis[N];
     36     vector<int> g[N];
     37     vector<DEdge> es;
     38     queue<int> q;
     39     void init(int n) {
     40         this->n=n;
     41         es.clear();
     42         FOR(i,0,n) g[i].clear();
     43     }
     44     void clear() {
     45         FOR(i,0,(int)es.size()-1) es[i].flow=0;
     46     }
     47     void AddEdge(int u,int v,ll w) {
     48         es.push_back((DEdge){u,v,w,0});
     49         es.push_back((DEdge){v,u,0,0});
     50         m=es.size();
     51         g[u].push_back(m-2);
     52         g[v].push_back(m-1);
     53     }
     54     int bfs() {
     55         memset(vis,0,sizeof(vis));
     56         q.push(s); d[s]=0; vis[s]=1;
     57         while(!q.empty()) {
     58             int u=q.front(); q.pop();
     59             FOR(i,0,(int)g[u].size()-1) {
     60                 DEdge& e=es[g[u][i]];
     61                 int v=e.v;
     62                 if(!vis[v]&&e.cap>e.flow) {
     63                     vis[v]=1;
     64                     d[v]=d[u]+1;
     65                     q.push(v);
     66                 }
     67             }
     68         }
     69         return vis[t];
     70     }
     71     ll dfs(int u,ll a) {
     72         if(u==t||!a) return a;
     73         ll flow=0,f;
     74         for(int& i=cur[u];i<g[u].size();i++) {
     75             DEdge& e=es[g[u][i]];
     76             int v=e.v;
     77             if(d[v]==d[u]+1&&(f=dfs(v,min(a,e.cap-e.flow)))>0) {
     78                 e.flow+=f; 
     79                 es[g[u][i]^1].flow-=f;
     80                 flow+=f; a-=f;
     81                 if(!a) break;
     82             }
     83         }
     84         return flow;
     85     }
     86     ll MaxFlow(int s,int t) {
     87         this->s=s,this->t=t;
     88         ll flow=0;
     89         while(bfs()) {
     90             memset(cur,0,sizeof(cur));
     91             flow+=dfs(s,llinf);
     92         }
     93         return flow;
     94     }
     95 } dc;
     96 
     97 struct Edge {
     98     int u,v;ll w; int nxt;
     99 }e[M];
    100 int en=1,front[N];
    101 void adde(int u,int v,ll w) 
    102 {
    103     e[++en]=(Edge){u,v,w,front[u]}; front[u]=en;
    104 }
    105 
    106 int n,m;
    107 ll c[N],dis1[N],dis2[N];
    108 
    109 int inq[N]; queue<int> q;
    110 void spfa(int s,ll* dis)
    111 {
    112     memset(inq,0,sizeof(inq));
    113     FOR(i,0,n) dis[i]=llinf;
    114     q.push(s); inq[s]=1; dis[s]=0;
    115     while(!q.empty()) {
    116         int u=q.front(); q.pop();
    117         inq[u]=0;
    118         trav(u,i) {
    119             int v=e[i].v;
    120             if(dis[v]>dis[u]+(ll)e[i].w) {
    121                 dis[v]=dis[u]+(ll)e[i].w;
    122                 if(!inq[v]) {
    123                     inq[v]=1; q.push(v);
    124                 }
    125             }
    126         }
    127     }
    128 }
    129 
    130 int main()
    131 {
    132     n=read(),m=read();
    133     FOR(i,1,m) {
    134         int u=read(),v=read(); ll w=read();
    135         adde(u,v,w),adde(v,u,w);
    136     }
    137     dc.init(n*2+2);
    138     spfa(1,dis1),spfa(n,dis2);
    139     ll dist=dis1[n];
    140     FOR(i,1,n)
    141         c[i]=read(),dc.AddEdge(i,i+n,c[i]);
    142     for(int i=2;i<=en;i+=2) {
    143         int u=e[i].u,v=e[i].v;
    144         if(dis1[u]>dis1[v]) swap(u,v);
    145         if((ll)dis1[u]+e[i].w+dis2[v]==dist)
    146             dc.AddEdge(u+n,v,inf),dc.AddEdge(v+n,u,inf);
    147     }
    148     printf("%lld
    ",dc.MaxFlow(n+1,n));
    149     return 0;
    150 }

    P.S. spfa写错还浑然不知,省选药丸的节奏QWQ

  • 相关阅读:
    Android笔记之spinner的使用
    Android笔记之AlertDialog使用
    Android笔记之intent使用(一)
    Android笔记之Editext使用
    Android控件之Textiew的使用
    Fastboot常用命令集,完美取代Recovery的所有功能
    Android笔记之WebView
    Android程序下重启手机
    Android笔记之ListView组件的使用
    intellij idea设置(字体大小、背景)
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5310495.html
Copyright © 2011-2022 走看看