比赛 20140423 评测结果 AAWWWWWWWW
题目名称 栅格网络流 最终得分 20
用户昵称 Chenyao2333 运行时间 0.034 s
代码语言 C++ 内存使用 0.51 MiB
提交时间 2014-04-23 11:03:44
显示代码纯文本
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<string.h>
#include<vector>

using namespace std;

const int MAXN=110*110;
const int INF=10000*10000;

struct edge{
	int to,cost;
};

int N,M;

struct spfa{
	vector<edge> edges;
	vector<int> G[MAXN];
	
	int s,t;
	
	void init(){
		s=t=0;
		edges.clear();
		for(int i=0;i<MAXN;i++)G[i].clear();
	}
	
	void add_edge(int from,int to,int cost){
		//cout<<from<<" "<<to<<" "<<cost<<endl;
		edges.push_back((edge){to,cost});
		edges.push_back((edge){from,cost});
		int m=edges.size();
		G[from].push_back(m-2);
		G[to].push_back(m-1);
	}
	
	int d[MAXN];bool inq[MAXN];
	int min_cost(){
		for(int i=0;i<MAXN;i++)d[i]=INF;
		memset(inq,0,sizeof(inq));
		queue<int> q;
		q.push(s);inq[s]=true;
		d[s]=0;
		while(!q.empty()){
			int u=q.front();q.pop();inq[t]=false;
			for(int i=0;i<G[u].size();i++){
				edge & e=edges[G[u][i]];
				if(d[e.to]>d[u]+e.cost){
					d[e.to]=d[u]+e.cost;
					if(!inq[e.to]){
						inq[e.to]=true;
						q.push(e.to);
					}
				}
			}
		}
		return d[t];
	}
}solver;

int cal_num(int x,int y){//方块 坐标 
	int n=N-1;
	int m=M-1;
	if(x==0 || y>m)return 0;
	if(x>n || y==0)return (N-1)*(M-1)+1;
	return (x-1)*n+y;
}

int cal_left_down(int x,int y){
	x=x+1;
	return cal_num(x,y);
}

int cal_right_down(int x,int y){
	x=x+1;y=y+1;
	return cal_num(x,y);
}

int cal_right_up(int x,int y){
	y=y+1;
	return cal_num(x,y);
}

void read_and_build(){
	solver.init();
	scanf("%d %d",&N,&M); 
	//H(N*(M-1)),V((N-1)*M),H[i][j]表示(i,j)->(i,j+1)的流量;
	for(int i=0;i<N;i++){
		for(int j=0;j<M-1;j++){
			int cost;scanf("%d",&cost);
			int u=cal_right_up(i,j);
			int v=cal_right_down(i,j);
			solver.add_edge(u,v,cost); 
		}
	}
	
	for(int i=0;i<N-1;i++){
		for(int j=0;j<M;j++){//V[i][j]表示(i,j)->(i+1,j)的流量
			int cost;scanf("%d",&cost);
			int u=cal_left_down(i,j);
			int v=cal_right_down(i,j);
			solver.add_edge(u,v,cost); 
		}
	}
	solver.s=0;solver.t=(N-1)*(M-1)+1;
}

void solve(){
	read_and_build();
	int ans=solver.min_cost();
	printf("%d\n",ans);
}

int main(){
	freopen("flowa.in","r",stdin);
	freopen("flowa.out","w",stdout);
	//freopen("in.txt","r",stdin);
	int T;scanf("%d",&T);
	while(T-->0){
		solve();
	}
	return 0;
}