题目:https://www.luogu.org/problemnew/show/P1344
那个边数的限制,只要把边权乘1001再+1即可。乘1001是因为有1000条边,这样流量小的不会因为边数多而被认为不优。不是乘1000是为了/1001和%1001取出答案,1000的话略有冲突。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=35,M=1005; const ll INF=0x3f3f3f3f3f3f3f3f; int n,m,hd[N],cur[N],xnt=1,dfn[N]; int q[N],he,tl; ll mxflow; struct Ed{ int nxt,to,cap; Ed(int n=0,int t=0,int c=0):nxt(n),to(t),cap(c) {} }ed[M<<1]; void add(int x,int y,int z) { ed[++xnt]=Ed(hd[x],y,z);hd[x]=xnt; ed[++xnt]=Ed(hd[y],x,0);hd[y]=xnt; } bool bfs() { memset(dfn,0,sizeof dfn); dfn[1]=1; he=tl=0; q[++tl]=1; while(he<tl) { int k=q[++he]; for(int i=hd[k],v;i;i=ed[i].nxt) if(ed[i].cap&&!dfn[v=ed[i].to]) dfn[v]=dfn[k]+1,q[++tl]=v; } return dfn[n]; } ll dinic(int cr,ll flow) { if(cr==n) return flow; ll use=0; for(int &i=cur[cr],v;i;i=ed[i].nxt) if(dfn[v=ed[i].to]==dfn[cr]+1&&ed[i].cap) { ll tmp=dinic(v,min(flow-use,(ll)ed[i].cap)); if(!tmp) dfn[v]=0; ed[i].cap-=tmp; ed[i^1].cap+=tmp; use+=tmp; if(use==flow) return use; } return use; } int main() { scanf("%d%d",&n,&m); for(int i=1,u,v,z;i<=m;i++) { scanf("%d%d%d",&u,&v,&z); add(u,v,z*1001+1); } while(bfs()) { memcpy(cur,hd,sizeof hd); mxflow+=dinic(1,INF); } printf("%lld %lld ",mxflow/1001,mxflow%1001); return 0; }