网络流第一题!!!BZOJ1001
歇逼了一晚上,懵懵懂懂的懂了Dinic算法
大概是一遍BFS+DFS,还不是很懂,明天继续看!!!
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int maxn = 1000010; const int inf = 0x3f3f3f3f; struct edge{ int to,next,w; }e[maxn<<3]; int n,m,cnt=1; int head[maxn]; int ans; int d[maxn]; void link(int u,int v,int w){//建立双向边 e[++cnt]=(edge){v,head[u],w};head[u]=cnt; e[++cnt]=(edge){u,head[v],w};head[v]=cnt; } bool bfs(){ memset(d,-1,sizeof(d)); queue<int> q;q.push(1);d[1]=0; while(!q.empty()){ int x=q.front(); q.pop(); for (int i=head[x];i;i=e[i].next){ if (e[i].w && d[e[i].to]<0){ q.push(e[i].to); d[e[i].to]=d[x]+1; } } } return d[n*m]<0 ? 0:1; } int dfs(int x,int f){ if (x==n*m || f==0)return f; int w,used=0; for (int i=head[x];i;i=e[i].next)if (e[i].w && d[e[i].to]==d[x]+1) { w=dfs(e[i].to,min(f-used,e[i].w)); e[i].w-=w; e[i^1].w+=w; used+=w; if (used==f)return f; } if (!used)d[x]=-1; return used; } void Dinic(int s){ while(bfs())ans+=dfs(s,inf); } int main(){ int x; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ for (int j=1;j<m;j++){ scanf("%d",&x); link(m*(i-1)+j,m*(i-1)+j+1,x);//求出边权连接的左右两个点 } } for (int i=1;i<n;i++){ for (int j=1;j<=m;j++){ scanf("%d",&x); link(m*(i-1)+j,m*i+j,x);//求出边权连接的上下两个点 } } for (int i=1;i<n;i++){ for (int j=1;j<m;j++){ scanf("%d",&x); link(m*(i-1)+j,m*i+j+1,x);//斜边上两个点 } } Dinic(1); printf("%d",ans); return 0; }