平面圖的最小割轉最短路(點非常多)
阿新 • • 發佈:2019-01-25
/************************************************************** User: error408 Language: C/C++ School: SSDUT Saying: Do one thing at a time,and do well. ****************************************************************/ #include <iostream> #include <vector> #include <map> #include <set> #include <queue> #include <stack> #include <algorithm> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <ctime> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") /// kuo zhan #define clr(s,x) memset((s),(x),sizeof(s)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lowbit(x) (x&(-x)) #define PB push_back #define For(i,a,b) for(int i=a;i<b;i++) #define FOR(i,a,b) for(int i=a;i<=b;i++) #define RL(N) scanf("%I64d",&N) #define RLL(L,R) (RL(L),RL(R)) typedef long long LL; typedef unsigned int uint; typedef unsigned long long ULL; typedef vector<int> vint; typedef vector<string> vstring; void RI (int& x){ x = 0; char c = getchar (); while (c == ' '||c == '\n') c = getchar (); bool flag = 1; if (c == '-'){ flag = 0; c = getchar (); } while (c >= '0' && c <= '9'){ x = x * 10 + c - '0'; c = getchar (); } if (!flag) x = -x; } void RII (int& x, int& y){RI (x), RI (y);} void RIII (int& x, int& y, int& z){RI (x), RI (y), RI (z);} /************************************END DEFINE*********************************************/ const int maxn = 1e6 + 1000; const int maxm = 4e6 + 1000; const int inf = 0x7fffffff; struct Side{ int to,next,w; }side[maxm]; int n,m,T,s,e,cnt; int top,node[maxn]; inline void add_side(int u,int v,int c){ side[top]=(Side){v,node[u],c}; node[u]=top++; side[top]=(Side){u,node[v],c}; node[v]=top++; } bool inque[maxn]; int dis[maxn]; int q[maxn]; int spfa(){ int head,tail; head = tail = 0; for(int i=0;i<cnt;i++){ dis[i]=inf; inque[i]=false; } dis[s]=0; q[tail++]=s; while(head!=tail){ int u=q[head++]; head%=maxn; inque[u]=false; for(int i=node[u];i!=-1;i=side[i].next){ int v=side[i].to; if(dis[u]+side[i].w<dis[v]){ dis[v]=dis[u]+side[i].w; if(!inque[v]){ inque[v]=true; q[tail++]=v; tail%=maxn; } } } } return dis[e]; } void init(){ top = 0; clr(node,-1); } int main() { scanf("%d",&T); while(T--){ init(); scanf("%d%d",&n,&m); s = (n-1)*(m-1); e = (n-1)*(m-1)+1; cnt = (n-1)*(m-1)+2; int w; for(int i=0;i<n-1;i++){ scanf("%d",&w); add_side(e,i*(m-1),w); for(int j=1;j<m-1;j++){ scanf("%d",&w); add_side(i*(m-1)+j,i*(m-1)+j-1,w); } scanf("%d",&w); add_side(s,i*(m-1)+m-2,w); } for(int j=0;j<m-1;j++){ scanf("%d",&w); add_side(j,s,w); } for(int i=1;i<n-1;i++) for(int j=0;j<m-1;j++){ scanf("%d",&w); add_side(i*(m-1)+j,(i-1)*(m-1)+j,w); } for(int j=0;j<m-1;j++){ scanf("%d",&w); add_side(e,(n-2)*(m-1)+j,w); } printf("%d\n",spfa()); } return 0; }