题意:给定一张平面图,求其最小割
题解:这里
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <queue> #include <functional> #include <cstdio> #include <climits> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXM=6000000+2; struct HASH{ int u,w; HASH *next; HASH(){} HASH(int _u,int _w,HASH *_next):u(_u),w(_w),next(_next){} }*table[MAXM],mem[MAXM]; struct EDGE{ int u,w; EDGE(){} EDGE(int _u,int _w):u(_u),w(_w){} bool friend operator<(EDGE a,EDGE b){ return a.w>b.w;} }; int N,M,cnt,d[MAXM]; priority_queue<EDGE> q; void Insert(int u,int v,int w){ table[u]=&(mem[cnt++]=HASH(v,w,table[u])); table[v]=&(mem[cnt++]=HASH(u,w,table[v])); } int Calc(int x,int y,bool t){ int ret=((M-1)*(x-1)+y-1)*2+1; if(t) ret++; return ret+1; } int Query(int N){ int ret=INT_MAX; for(int i=1,t;i<N;i++){ scanf("%d",&t); ret=min(ret,t); } return ret; } int Dijkstra(int s,int t){ memset(d,0X7F,sizeof(d)); d[s]=0,q.push(EDGE(s,0)); int x; while(!q.empty()){ x=q.top().u,q.pop(); for(HASH *p=table[x];p;p=p->next) if(d[p->u]>d[x]+p->w){ d[p->u]=d[x]+p->w; q.push(EDGE(p->u,d[p->u])); } } return d[t]; } int main(){ scanf("%d %d",&N,&M); if(N==1 || M==1){ cout << Query(max(N,M)) << endl; return 0; } for(int i=1,w;i<=N;i++) for(int j=1;j<M;j++){ scanf("%d",&w); if(i==1) Insert(Calc(i,j,1),0,w); else if(i==N) Insert(Calc(i-1,j,0),1,w); else Insert(Calc(i,j,1),Calc(i-1,j,0),w); } for(int i=1,w;i<N;i++) for(int j=1;j<=M;j++){ scanf("%d",&w); if(j==1) Insert(Calc(i,j,0),1,w); else if(j==M) Insert(Calc(i,j-1,1),0,w); else Insert(Calc(i,j-1,1),Calc(i,j,0),w); } for(int i=1,w;i<N;i++) for(int j=1;j<M;j++){ scanf("%d",&w); Insert(Calc(i,j,0),Calc(i,j,1),w); } cout << Dijkstra(0,1) << endl; return 0; }