2 条题解
-
0
#include<bits/stdc++.h> using namespace std; const int N = 1210; typedef long long LL; struct edge { LL x,cap,rev; }; int g[N][N]; vector<edge> e[N]; int n,m,s,t; int d[N],it[N]; void add(int a,int b,int c) { e[a].push_back({b,c,e[b].size()}); e[b].push_back({a,0,e[a].size() - 1}); } void bfs() { memset(d,-1,sizeof d); queue<int> q; d[s] = 0; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); for(auto t : e[u]) if(t.cap > 0 && d[t.x] < 0) d[t.x] = d[u] + 1,q.push(t.x); } } LL dfs(int u,LL f) { if(u == t) return f; for(int &i = it[u]; i < e[u].size(); i ++) { edge &t = e[u][i]; if(d[u] < d[t.x] && t.cap > 0) { LL d = dfs(t.x,min(f,t.cap)); if(d > 0) { t.cap -= d; e[t.x][t.rev].cap += d; return d; } } } return 0; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>m>>s>>t; for(int i = 1; i <= m; i ++) { int x,y,z; cin>>x>>y>>z; g[x][y] += z; } LL flow = 0; for(int i = 28; i >= 0; i -= 4) { for(int x = 1; x <= n; x ++) for(int y = 1; y <= n; y ++) if(g[x][y] >= (1 << i)) add(x,y,g[x][y]),g[x][y] = 0; while(1) { bfs(); if(d[t] < 0) break; memset(it,0,sizeof it); LL d = dfs(s,1e18); while(d > 0) { flow += d; d = dfs(s,1e18); } } } cout<<flow<<endl; return 0; } -
0
#include<bits/stdc++.h>//44分的代码(只优化了当前弧),正常dinic28分 using namespace std; typedef long long LL; const int N=1300,M=250000; struct node{int x,y;LL f; int pre;}a[M];int alen,last[N],cur[N]; void ins(int x,int y,LL f) { alen++;a[alen]=node{x,y,f,last[x]};last[x]=alen; alen++;a[alen]=node{y,x,0,last[y]};last[y]=alen; } int h[N],st,ed,n,m; bool bfs() { deque<int>q;q.clear(); memset(h,0,sizeof(h));h[st]=1; q.push_back(st); while(!q.empty()) { int x=q.front();q.pop_front(); for(int k=last[x];k>0;k=a[k].pre)if(a[k].f) { int y=a[k].y; if(h[y]==0) { h[y]=h[x]+1; q.push_back(y); } } } return h[ed]>0; } LL dinic(int x,LL f) { if(x==ed)return f; LL sx=0; for(int k=cur[x];k;k=a[k].pre)if(a[k].f) { int y=a[k].y; cur[x]=k;//k之前的边对于x已经没有意义 if(h[y]==h[x]+1) { LL sy=dinic(y,min(a[k].f,f-sx)); a[k].f-=sy;a[k^1].f+=sy; sx+=sy;if(sx==f)return f; } } if(sx==0)h[x]=0; return sx; } int main() { scanf("%d%d%d%d",&n,&m,&st,&ed); alen=1;memset(last,0,sizeof(last)); for(int i=1;i<=m;i++) { int x,y;LL f;scanf("%d%d%lld",&x,&y,&f); ins(x,y,f); } //dinic过程:如果存在层次图就探索存在的流 LL s=0; while( bfs() ) { memcpy(cur,last,sizeof(int)*(n+2)); s+=dinic(st,(LL)1<<62); } printf("%lld",s); return 0; }
bool _Start;// by Lofty #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> namespace IO { #define TP template<typename T> #define TP_ template<typename T,typename ... T_> #ifdef DEBUG #define gc() (getchar()) #else char buf[1<<20],*p1,*p2; #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++) #endif #ifdef DEBUG void pc(const char &c) { putchar(c); } #else char pbuf[1<<20],*pp=pbuf; void pc(const char &c) { if(pp-pbuf==1<<20) fwrite(pbuf,1,1<<20,stdout),pp=pbuf; *pp++=c; } struct IO{~IO(){fwrite(pbuf,1,pp-pbuf,stdout);}}_; #endif TP void read(T &x) { x=0;static int f;f=0;static char ch;ch=gc(); for(;ch<'0'||ch>'9';ch=gc())ch=='-'&&(f=1); for(;ch>='0'&&ch<='9';ch=gc())x=(x<<1)+(x<<3)+(ch^48); f&&(x=-x); } TP void write(T x) { if(x<0) pc('-'),x=-x; static T sta[35],top;top=0; do sta[++top]=x%10,x/=10; while(x); while(top) pc(sta[top--]^48); } TP_ void read(T &x,T_&...y){read(x);read(y...);} TP void writeln(const T x){write(x);pc('\n');} TP void writesp(const T x){write(x);pc(' ');} TP_ void writeln(const T x,const T_ ...y){writesp(x);writeln(y...);} TP void debugsp(const T x){fprintf(stderr,"%d ",x);} TP void debug(const T x){fprintf(stderr,"%d\n",x);} TP_ void debug(const T x,const T_...y){debugsp(x);debug(y...);} TP inline T max(const T &a,const T &b){return a>b?a:b;} TP_ inline T max(const T &a,const T_&...b){return max(a,max(b...));} TP inline T min(const T &a,const T &b){return a<b?a:b;} TP_ inline T min(const T &a,const T_&...b){return min(a,min(b...));} TP inline void swap(T &a,T &b){static T t;t=a;a=b;b=t;} TP inline T abs(const T &a){return a>0?a:-a;} #undef TP #undef TP_ } using namespace IO; using std::cerr; using PII=std::pair<int,int>; using LL=long long; constexpr int N=5e3+10,M=3e5+10,inf=0x3f3f3f3f; int n,m,st,ed; LL w[N]; int h[N],gap[N<<1],cur[N]; struct edge { int y;LL f;int other; }; std::vector<edge>a[N]; inline void ins(int x,int y,LL f) { a[x].push_back({y,f,(int)a[y].size()}); a[y].push_back({x,0,(int)a[x].size()-1}); } struct cmp { inline bool operator()(const int &x,const int &y)const { return h[x]<h[y];//队内高度不会改变,必须先出队再改,优先队列只在插入和出队时排序 } }; bool bfs()//给所有点一个初始的高度,选择最短路的原因是推流的点最少 { static std::queue<int>q; memset(h,0x3f,sizeof(h)); h[ed]=1; q.push(ed); while(q.size()) { int x=q.front();q.pop(); for(auto k:a[x]) { int y=k.y; if(a[y][k.other].f&&h[y]>h[x]+1) { h[y]=h[x]+1; q.push(y); } } } return h[st]!=h[0]; } bool inq[N]; std::priority_queue<int,std::vector<int>,cmp>q;//按高度排序的大根堆 inline void push(int x)//对 x 点的余流推流出去 { for(int &i=cur[x];i<(int)a[x].size();i++)//当前弧优化,若保留了当前弧,说明目前余流不足,还可以需要再推流 { edge &k=a[x][i]; int y=k.y; if(k.f&&h[y]==h[x]-1)//可以流且是一条合法的推流路径 { LL f=min(w[x],k.f); w[x]-=f;w[y]+=f; k.f-=f; a[y][k.other].f+=f; if(y!=st&&y!=ed&&!inq[y])//加入队列。注意起点和终点不能入队,因为起点有无限余流,终点只接收,没有余流 q.push(y),inq[y]=1; if(!w[x])//没有余流可推了,自然要提前结束 return ;//这里必须是 return 而不是 break!否则当仍有边可推流时当前弧重置,优化就是假的!(@WisNourx_ 就是这个**写错) } } cur[x]=0;//如果还有余流,就再重新遍历,对应下面改变高度,流向新的路径 } inline void relabel(int x)//重新给一个高度 { h[x]=inf; for(auto k:a[x]) if(k.f&&h[k.y]+1<h[x])//往尽量低处流,因为最低点是终点 h[x]=h[k.y]+1; } LL HLPP() { if(!bfs())//提前给定高度,加速推流,否则需要再推流时给定,增加遍历数量 return 0; for(int i=1;i<=n;i++) if(h[i]<inf) ++gap[h[i]];//gap 优化,若一个高度已经全部流完,更高的是找不到低处流的 //并且 gap 需要开到 2n-1,最极端的情况可能会全部流回起点 h[st]=n;//若其他点流完找不到低处,就要流回起点方向,为防可能流向其他方向,应定为 n,这样其他点在初始情况下是不可能高于起点的 for(auto &k:a[st])//在起点做一次无限流量的推流 { int y=k.y; if(k.f&&h[y]<inf) { LL f=k.f; w[st]-=f;w[y]+=f; k.f-=f; a[y][k.other].f+=f; if(y!=st&&y!=ed&&!inq[y])//加入队列。注意起点和终点不能入队,因为起点有无限余流,终点只接收,没有余流 q.push(y),inq[y]=1; } } while(q.size()) { int x=q.top();q.pop();inq[x]=0; push(x); if(w[x]) { if(--gap[h[x]]<=0)//没有该高度了 for(int i=1;i<=n;i++) if(i!=st&&i!=ed&&h[i]>h[x]&&h[i]<n+1)//那么比它更高的就没有低处流了,流回起点 h[i]=n+1; relabel(x);++gap[h[x]]; q.push(x);inq[x]=1; } } return w[ed]; } bool _End; int main() { // fprintf(stderr,"%.2 MBlf\n",(&_End-&_Start)/1048576.0); read(n,m,st,ed); for(int i=1,x,y,f;i<=m;i++) { read(x,y,f); ins(x,y,f); } writeln(HLPP()); return 0; }
- 1
信息
- ID
- 392
- 时间
- 1500ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- 递交数
- 168
- 已通过
- 14
- 上传者