更新!!!!
方格最小割转化为对偶图的最短路
https://blog.csdn.net/MaxMercer/article/details/77976666
只不过n==1||m==1的时候没法正常建图 特判以下就好了
/************************************************************** Problem: 1001 User: lxy8584099 Language: C++ Result: Accepted Time:2048 ms Memory:149404 kb ****************************************************************/ #include<queue> #include<cstdio> #include<cstring> #define mp make_pair #define pr pair<int,int> using namespace std; const int N=1050; struct pp {int v,nxt,d;} e[N*N*10]; int n,m,head[N*N*2],tot,dis[N*N*2],st,ed; bool vis[N*N*2]; priority_queue< pr > q; void add(int u,int v,int d) { // printf("%d->%d : %d\n",u,v,d); e[++tot].nxt=head[u];head[u]=tot;e[tot].v=v;e[tot].d=d; e[++tot].nxt=head[v];head[v]=tot;e[tot].v=u;e[tot].d=d; } void dij() { memset(dis,0x3f,sizeof(dis)); dis[st]=0;q.push(mp(0,st)); while(!q.empty()) { int u=q.top().second;q.pop(); if(vis[u]) continue; vis[u]=1; for(int j=head[u];j;j=e[j].nxt) { int v=e[j].v,d=e[j].d; if(dis[v]>dis[u]+d) { dis[v]=dis[u]+d; q.push(mp(-dis[v],v)); } } } } int main() { scanf("%d%d",&n,&m);// 3 4 if(m==1) { int res=2e9;for(int i=1,x;i<n;i++) scanf("%d",&x),res=res>x?x:res; printf("%d\n",res);return 0; } if(n==1) { int res=2e9;for(int i=1,x;i<m;i++) scanf("%d",&x),res=res>x?x:res; printf("%d\n",res);return 0; } st=(n-1)*(m-1)*2+1,ed=st+1; for(int i=1;i<=n;i++) for(int j=1,x;j<m;j++) { scanf("%d",&x); if(i==1) add((i-1)*(m-1)*2+j*2,ed,x); else if(i==n) add(st,(i-2)*(m-1)*2+(j-1)*2+1,x); else add((i-2)*(m-1)*2+(j-1)*2+1,(i-1)*(m-1)*2+j*2,x); } for(int i=1;i<n;i++) for(int j=1,x;j<=m;j++) { scanf("%d",&x); if(j==1) add(st,(i-1)*(m-1)*2+(j-1)*2+1,x); else if(j==m) add((i-1)*(m-1)*2+(j-1)*2,ed,x); else add((i-1)*(m-1)*2+(j-1)*2,(i-1)*(m-1)*2+(j-1)*2+1,x); } for(int i=1;i<n;i++) for(int j=1,x;j<m;j++) { scanf("%d",&x); add((i-1)*(m-1)*2+(j-1)*2+1,(i-1)*(m-1)*2+j*2,x); } dij();printf("%d\n",dis[ed]); return 0; }
最小割
/************************************************************** Problem: 1001 User: lxy8584099 Language: C++ Result: Accepted Time:1932 ms Memory:117132 kb ****************************************************************/ /* 要拦住所有兔子就要把这个图切断 就是这个图的最小割 = 最大流 注意双向边! (看成单向结果样例答案只有 11 ) */ #include<cstdio> #include<queue> #include<cstring> #define min(a,b) ((a>b)?(b):(a)) #define inf (0x3fffffff) using namespace std; const int N=1e3+50; struct pp {int v,nxt,c;}e[(N*N)<<3]; int n,m,tot=1,head[N*N],cur[N*N]; int dep[N*N],st,ed; void add(int u,int v,int c) { e[++tot].nxt=head[u];head[u]=tot; e[tot].v=v;e[tot].c=c; e[++tot].nxt=head[v];head[v]=tot; e[tot].v=u;e[tot].c=c; } void init() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<m;j++) { int c;scanf("%d",&c);add((i-1)*m+j,(i-1)*m+j+1,c); } for(int i=1;i<n;i++) for(int j=1;j<=m;j++) { int c;scanf("%d",&c); add((i-1)*m+j,i*m+j,c); } for(int i=1;i<n;i++) for(int j=1;j<m;j++) { int c;scanf("%d",&c); add((i-1)*m+j,i*m+j+1,c); } st=n*m+1;ed=st+1; add(st,1,inf);add(n*m,ed,inf); } bool bfs() { queue<int> q; memset(dep,0,sizeof(dep)); q.push(st); dep[st]=1; while(!q.empty()) { int u=q.front();q.pop(); for(int j=head[u];j;j=e[j].nxt) { int v=e[j].v; if(e[j].c>0&&!dep[v]) { dep[v]=dep[u]+1; q.push(v); } } } return dep[ed]; } int dfs(int u,int now) { if(u==ed||now==0) return now; int val=0,s; for(int&j=cur[u];j;j=e[j].nxt) { int v=e[j].v; if(dep[v]==dep[u]+1&&e[j].c>0) { val+=(s=dfs(v,min(now-val,e[j].c))); e[j].c-=s;e[j^1].c+=s; if(val==now) break; } } if(val==0) dep[u]=0; return val; } int main() { init(); int ans=0; while(bfs()) { memcpy(cur,head,sizeof(head)); int res;while(res=dfs(1,inf)) ans+=res; } printf("%d\n",ans); return 0; }

京公网安备 11010502036488号