BZOJ3931 CQOI2015 网络吞吐量 最短路+网络流
题意:求1到N的所有最短路方案上的最大流,阈值在每个点上
题解:呵呵哒
#include <queue> #include <vector> #include <functional> #include <cstdio> #include <cstring> #include <cstdlib> #include <climits> #include <iostream> #include <algorithm> using namespace std; #define ll long long #define INF 0x3f3f3f3f3f3f3f3fll const int MAXN=1000+2; const int MAXM=400000+2; struct HASH{ int u; ll w; HASH *next; HASH(){} HASH(int _u,ll _w,HASH *_next):u(_u),w(_w),next(_next){} }*table[MAXN],mem[MAXM]; struct EDGE{ int u; ll c; EDGE(){} EDGE(int _u,ll _c):u(_u),c(_c){} bool friend operator<(EDGE a,EDGE b){ return a.c>b.c;} }e[MAXM]; int N,M,cur[MAXN],cnt; ll d[MAXN]; bool flag[MAXN]; queue<int> q; vector<int> tab[MAXN]; priority_queue<EDGE> pq; void Insert1(int u,int v,ll w){ for(HASH *p=table[u];p;p=p->next) if(p->u==v){ p->w=min(w,p->w); return; } table[u]=&(mem[cnt++]=HASH(v,w,table[u])); } void Insert2(int u,int v,ll c){ tab[u].push_back(cnt),e[cnt++]=EDGE(v,c); tab[v].push_back(cnt),e[cnt++]=EDGE(u,0); } void Dijkstra(){ for(int i=1;i<=N;i++) d[i]=INF; d[1]=0,pq.push(EDGE(1,0)),flag[1]=1; int x; while(!pq.empty()){ x=pq.top().u,pq.pop(); for(HASH *p=table[x];p;p=p->next) if(d[p->u]>d[x]+p->w){ d[p->u]=d[x]+p->w; if(!flag[p->u]) pq.push(EDGE(p->u,d[p->u])); } flag[x]=0; } } bool BFS(int s,int t){ memset(d,-1,sizeof(d)); d[s]=0,q.push(s); int x; while(!q.empty()){ x=q.front(),q.pop(); for(int i=0;i<tab[x].size();i++) if(d[e[tab[x][i]].u]==-1 && e[tab[x][i]].c) d[e[tab[x][i]].u]=d[x]+1,q.push(e[tab[x][i]].u); } return d[t]>0; } ll DFS(int x,ll f,int t){ if(x==t) return f; ll flow,used=0; for(int i=cur[x];i<tab[x].size();i++) if(e[tab[x][i]].c && d[e[tab[x][i]].u]==d[x]+1){ flow=DFS(e[tab[x][i]].u,min(f-used,e[tab[x][i]].c),t); e[tab[x][i]].c-=flow,e[tab[x][i]^1].c+=flow,used+=flow; if(e[tab[x][i]].c) cur[x]=i; if(f==used) return f; } if(!used) d[x]=-1; return used; } ll Dinic(int s,int t){ ll ret=0; while(BFS(s,t)){ memset(cur,0,sizeof(cur)); ret+=DFS(s,INF,t); } return ret; } int main(){ scanf("%d %d",&N,&M); for(int i=1,u,v,w;i<=M;i++){ scanf("%d %d %d",&u,&v,&w); Insert1(u,v,w),Insert1(v,u,w); } Dijkstra(); cnt=0; for(int i=1,c;i<=N;i++){ scanf("%d",&c); Insert2(i,N+i,c); } for(int i=1;i<=N;i++) for(HASH *p=table[i];p;p=p->next) if(d[p->u]==d[i]+p->w) Insert2(N+i,p->u,INF); printf("%lld\n",Dinic(N+1,N)); return 0; }