n<=1000 * m<=1000的网格图(见下)问最小割。
emmm上论文 好东西
然而建边建错WA*3,调试忘删WA*1。
非常好。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<stdlib.h> 5 #include<queue> 6 #include<math.h> 7 //#include<time.h> 8 #include<iostream> 9 using namespace std; 10 11 int n,m; 12 #define maxn 2000011 13 #define maxm 6000011 14 #define LL long long 15 struct Edge{int to,next,v;}edge[maxm];int first[maxn],le=2; 16 void in(int x,int y,int v) {Edge &e=edge[le];e.to=y;e.v=v;e.next=first[x];first[x]=le++;} 17 void insert(int x,int y,int v) {in(x,y,v);in(y,x,v);} 18 19 int tot; 20 struct qnode 21 { 22 int id;LL v; 23 bool operator > (const qnode &b) const {return v>b.v;} 24 }; 25 priority_queue<qnode,vector<qnode>,greater<qnode> > q; 26 LL dis[maxn];bool vis[maxn]; 27 LL dijkstra(int s,int t) 28 { 29 for (int i=1;i<=tot;i++) dis[i]=1e18; 30 dis[s]=0; 31 q.push((qnode){s,0}); 32 while (!q.empty()) 33 { 34 const int now=q.top().id; q.pop(); 35 if (vis[now]) continue; 36 vis[now]=1; 37 for (int i=first[now];i;i=edge[i].next) 38 { 39 const Edge &e=edge[i]; 40 if (dis[e.to]>dis[now]+e.v) 41 { 42 dis[e.to]=dis[now]+e.v; 43 q.push((qnode){e.to,dis[e.to]}); 44 } 45 } 46 } 47 return dis[t]; 48 } 49 50 int main() 51 { 52 scanf("%d%d",&n,&m); 53 if (n==1 || m==1) 54 { 55 if (m==1) swap(n,m); 56 int ans=0x3f3f3f3f; 57 for (int i=1,x;i<m;i++) scanf("%d",&x),ans=min(ans,x); 58 printf("%d ",ans); 59 return 0; 60 } 61 tot=(n-1)*(m-1)*2+2; int s=tot-1,t=tot; 62 for (int j=1,x;j<m;j++) scanf("%d",&x),insert(t,j,x); 63 for (int i=2;i<=n-1;i++) 64 { 65 int u=(i-1)*(m-1),v=(i-2)*(m-1),w=(n-1)*(m-1); 66 for (int j=1,x;j<m;j++) 67 { 68 scanf("%d",&x); 69 insert(u+j,v+j+w,x); 70 } 71 } 72 for (int j=1,x;j<m;j++) scanf("%d",&x),insert((n-2)*(m-1)+j+(n-1)*(m-1),s,x); 73 74 for (int i=1,x;i<n;i++) 75 { 76 int w=(n-1)*(m-1),u=(i-1)*(m-1); 77 scanf("%d",&x); 78 insert(s,u+1+w,x); 79 for (int j=2;j<m;j++) 80 { 81 scanf("%d",&x); 82 insert(u+j-1,u+w+j,x); 83 } 84 scanf("%d",&x); 85 insert(t,u+m-1,x); 86 } 87 88 for (int i=1;i<n;i++) 89 { 90 int u=(i-1)*(m-1),v=(n-1)*(m-1); 91 for (int j=1,x;j<m;j++) 92 { 93 scanf("%d",&x); 94 insert(u+j,u+j+v,x); 95 } 96 } 97 98 printf("%lld ",dijkstra(s,t)); 99 return 0; 100 }