網路流之模板
阿新 • • 發佈:2019-01-22
dinic(二分圖中有優勢)
isap(普通圖中有優勢)//codevs 1993 #include <cstdio> #include <cstring> #include <queue> #define N 2000 #define INF 10000005 using namespace std; int tot=-1,next[N*4+5],point[N*4+5],v[N*4+5],remind[N*4+5],cur[N*4+5],deep[N*4+5],n,m; void addline(int x,int y,int cap) { ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; remind[tot]=cap; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x; remind[tot]=0; } bool bfs(int s,int t) { int i; queue <int> q; q.push(s); memset(deep,0x7f,sizeof(deep)); deep[s]=0; for (i=1;i<=m;i++) cur[i]=point[i]; while (!q.empty()) { int x=q.front(); q.pop(); for (i=point[x];i!=-1;i=next[i]) if (deep[v[i]]>INF && remind[i]) { q.push(v[i]); deep[v[i]]=deep[x]+1; } } return deep[t]<INF; } int dfs(int now,int t,int limit) { if (now==t||!limit) return limit; int flow=0,f; for (int i=cur[now];i!=-1;i=next[i]) { cur[now]=i; if (deep[v[i]]==deep[now]+1 && (f=dfs(v[i],t,min(limit,remind[i])))) { flow+=f; limit-=f; remind[i]-=f; remind[i^1]+=f; if (!limit) break; } } return flow; } int dinic(int s,int t) { int ans=0; while (bfs(s,t)) ans+=dfs(s,t,INF); return ans; } int main() { int i,a,b,cap; memset(next,-1,sizeof(next)); memset(point,-1,sizeof(point)); scanf("%d%d",&n,&m); for (i=1;i<=n;i++) { scanf("%d%d%d",&a,&b,&cap); addline(a,b,cap); } printf("%d",dinic(1,m)); }
#include <cstdio> #include <cstring> #include<iostream> #include<cstring> #include <queue> #define N 2000 #define INF 10000005 using namespace std; int tot=-1,next[N*4+5],point[N*4+5],v[N*4+5],remind[N*4+5],cur[N*4+5],deep[N*4+5],n,m,last[N*4+5],num[N*4+5],maxflow; void addline(int x,int y,int cap) { ++tot; next[tot]=point[x]; point[x]=tot; v[tot]=y; remind[tot]=cap; ++tot; next[tot]=point[y]; point[y]=tot; v[tot]=x; remind[tot]=0; } void bfs(int t) { queue<int>q; for (int i=1;i<=m;i++) deep[i]=m; deep[t]=0; q.push(t); while (!q.empty()) { int now=q.front(); q.pop(); for (int i=point[now];i!=-1;i=next[i]) if (deep[v[i]]==m && remind[i^1]) { deep[v[i]]=deep[now]+1; q.push(v[i]); } } } int addflow(int s,int t) { int ans=INF,now=t; while (now!=s) { ans=min(ans,remind[last[now]]); now=v[last[now]^1]; } now=t; while (now!=s) { remind[last[now]]-=ans; remind[last[now]^1]+=ans; now=v[last[now]^1]; } return ans; } void isap(int s,int t) { int now=s,i; bfs(t); for (i=1;i<=m;i++) ++num[deep[i]]; for (i=1;i<=m;i++) cur[i]=point[i]; while (deep[s]<m) { if (now==t) { maxflow+=addflow(s,t); now=s; } bool has_find=false; for (int i=cur[now];i!=-1;i=next[i]) { int u=v[i]; if (deep[u]+1==deep[now] && remind[i]) { has_find=true; cur[now]=i; last[u]=i; now=u; break; } } if (!has_find) { int minn=m-1; for (int i=point[now];i!=-1;i=next[i]) if (remind[i]) minn=min(minn,deep[v[i]]); if (!(--num[deep[now]])) break; num[deep[now]=minn+1]++; cur[now]=point[now]; if (now!=s) now=v[last[now]^1]; } } } int main() { int i,a,b,cap; memset(next,-1,sizeof(next)); memset(point,-1,sizeof(point)); scanf("%d%d",&n,&m); for (i=1;i<=n;i++) { scanf("%d%d%d",&a,&b,&cap); addline(a,b,cap); } isap(1,m); printf("%d",maxflow); }