[] CQOI2015 network throughput

Face questions

https://www.luogu.org/problem/P3171

answer

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
#define LL long long
#define ri register int
#define N 550
#define INF 1000000007
#define M 150000

using namespace std;

int n,m;
int du[N];

struct node {
  int u; LL d;
  bool operator < (const node &rhs) const {
    return d>rhs.d;
  }
};

struct graph {
  vector<int> to[N],len[N];
  LL dis[N];
  bool vis[N];
  void add_edge(int a,int b,int c) {
    to[a].push_back(b); len[a].push_back(c);
    to[b].push_back(a); len[b].push_back(c);
  }
  void dijkstra() {
    priority_queue<node> q;
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    q.push((node){1,0});
    while (!q.empty()) {
      int x=q.top().u; q.pop();
      if (vis[x]) continue;
      vis[x]=1;
      for (ri i=0,l=to[x].size();i<l;i++) {
        int y=to[x][i];
        if (dis[y]>dis[x]+len[x][i]) {
          dis[y]=dis[x]+len[x][i];
          q.push((node){y,dis[y]});
        }
      }
    }
  }
} g;

struct graph2 {
  vector<int> ed[N<<1];
  int cnt,w[M<<1],to[M<<1];
  int d[N<<1];
  int cur[N<<1];
  void add_edge(int a,int b,int c) {
    ed[a].push_back(++cnt); to[cnt]=b; w[cnt]=c;
    ed[b].push_back(++cnt); to[cnt]=a; w[cnt]=0;
  }
  void makegraph() {
    priority_queue<node> q;
    q.push((node){1,0});
    cnt=-1;
    while (!q.empty()) {
      int x=q.top().u; q.pop();
      for (ri i=0,l=g.to[x].size();i<l;i++) {
        int y=g.to[x][i];
        if (g.dis[y]==g.dis[x]+g.len[x][i]) {
          add_edge(2*x,2*y-1,INF);
          q.push((node){y,g.dis[y]});
        }
      }
    }
    for (ri i=1;i<=n;i++) add_edge(2*i-1,2*i,du[i]);
  }
  
  bool bfs() {
    queue<int> q;
    memset(d,0x3f,sizeof(d));
    d[2]=1;
    q.push(2);
    while (!q.empty()) {
      int x=q.front(); q.pop();
      for (ri i=0,l=ed[x].size();i<l;i++) {
        int e=ed[x][i];
        if (w[e] && d[x]+1<d[to[e]]) {
          d[to[e]]=d[x]+1;
          q.push(to[e]);
        }
      }
    }
    return d[2*n-1]<=2*n;
  }
  
  int dfs(int x,int limit) {
    if (x==2*n-1 || !limit) return limit;
    int used=0;
    for (ri &i=cur[x],l=ed[x].size();i<l;i++) {
      int e=ed[x][i];
      if (d[x]+1==d[to[e]] && w[e]) {
        int f=dfs(to[e],min(limit,w[e]));
        if (!f) continue;
        w[e]-=f; w[1^e]+=f;
        used+=f;limit-=f;
        if (limit==0) return used;
      }
    }
    return used;
  }
  LL dinic() {
    LL ret=0;
    while (bfs()) {
      memset(cur,0,sizeof(cur));
      ret+=dfs(2,INF);
    }
    return ret;
  }
} G2;

int main(){
  scanf("%d %d",&n,&m);
  int a,b,c;
  for (ri i=1;i<=m;i++) {
    scanf("%d %d %d",&a,&b,&c);
    g.add_edge(a,b,c);
  }
  for (ri i=1;i<=n;i++) scanf("%d",&du[i]);
  g.dijkstra();
  G2.makegraph();
  cout<<G2.dinic()<<endl;
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11277945.html