Description

 

You have a grid of n rows and n columns. Each of the unit squares contains a non-zero digit. You walk from the top-left square to the bottom-right square. Each step, you can move left, right, up or down to the adjacent square (you cannot move diagonally), but you cannot visit a square more than once. There is another interesting rule: your path must be symmetric about the line connecting the bottom-left square and top-right square. Below is a symmetric path in a 6 x 6 grid.

Your task is to find out, among all valid paths, how many of them have the minimal sum of digits?

Input

There will be at most 25 test cases. Each test case begins with an integer n ( 2n100). Each of the next n lines contains n non-zero digits (i.e. one of 1, 2, 3, ..., 9). These n2 integers are the digits in the grid. The input is terminated by a test case with n = 0, you should not process it.

Output

For each test case, print the number of optimal symmetric paths, modulo 1,000,000,009.

Sample Input

2
1 1
1 1
3
1 1 1
1 1 1
2 1 1
0

Sample Output

2
3
思路:要求是要关于那条线对称的,所一把上半角和下半角叠加起来,然后求到那条线的最短路即可,用迪杰斯特拉求。建图也比较简单,就是每个点向四个方向的点连边
。在求最短路的时候开一个数组记录当前走到该点的最短路有多少条就行,最后求到斜边点上等于最短路的种数和即可。
复杂度n*n
  1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string.h>
5 #include<math.h>
6 #include<queue>
7 #include<vector>
8 using namespace std;
9 int ma[200][200];
10 typedef struct pp
11 {
12 int x;
13 int y;
14 int cost;
15 int id;
16 bool flag;
17 } ss;
18 const int mod=1e9+9;
19 typedef long long LL;
20 LL sum[10005];
21 LL d[10005];
22 bool flag[10005];
23 ss node[10005];
24 vector<ss>vec[10005];
25 int dd[200][200];
26 void dj(int n,int id);
27 int main(void)
28 {
29 int i,j,k;
30 while(scanf("%d",&k),k!=0)
31 {
32 memset(dd,-1,sizeof(dd));
33 memset(flag,0,sizeof(flag));
34 memset(sum,0,sizeof(sum));
35 for(i=0;i<10005;i++)
36 vec[i].clear();
37 for(i=0; i<k; i++)
38 {
39 for(j=0; j<k; j++)
40 {
41 scanf("%d",&ma[i][j]);
42 }
43 }
44 for(i=0; i<k; i++)
45 {
46 for(j=0; j<(k-i); j++)
47 {
48 if(i+j!=k-1)
49 {
50 ma[i][j]+=ma[k-j-1][k-i-1];
51 }
52 }
53 }
54 int id=0;
55 for(i=0; i<k; i++)
56 {
57 for(j=0; j<(k-i); j++)
58 {
59 if(i+j==k-1)
60 {
61 node[id].flag=true;
62 node[id].x=i;
63 node[id].y=j;
64 node[id].id=id;
65 }
66 else
67 {
68 node[id].flag=false ;
69 node[id].x=i;
70 node[id].y=j;
71 node[id].id=id;
72 }
73 dd[i][j]=id;
74 if(i-1>=0)
75 {
76 ss cc;
77 cc.x=i-1;
78 cc.y=j;
79 cc.id=dd[i-1][j];
80 cc.cost=ma[i-1][j];
81 vec[id].push_back(cc);
82 cc.x=i;
83 cc.y=j;
84 cc.id=dd[i][j];
85 cc.cost=ma[i][j];
86 vec[dd[i-1][j]].push_back(cc);
87 }
88 if(j-1>=0)
89 {
90 ss cc;
91 cc.x=i;
92 cc.y=j-1;
93 cc.id=dd[i][j-1];
94 cc.cost=ma[i][j-1];
95 vec[id].push_back(cc);
96 cc.x=i;
97 cc.y=j;
98 cc.id=dd[i][j];
99 cc.cost=ma[i][j];
100 vec[dd[i][j-1]].push_back(cc);
101 }
102 if(i+1<k&&dd[i+1][j]!=-1)
103 {
104 ss cc;
105 cc.x=i+1;
106 cc.y=j;
107 cc.id=dd[i+1][j];
108 cc.cost=ma[i+1][j];
109 vec[id].push_back(cc);
110 cc.x=i;
111 cc.y=j;
112 cc.id=dd[i][j];
113 cc.cost=ma[i][j];
114 vec[dd[i+1][j]].push_back(cc);
115 }
116 if(j+1<k&&dd[i][j+1]!=-1)
117 {
118 ss cc;
119 cc.x=i;
120 cc.y=j+1;
121 cc.id=dd[i][j+1];
122 cc.cost=ma[i][j+1];
123 vec[id].push_back(cc);
124 cc.x=i;
125 cc.y=j;
126 cc.id=dd[i][j];
127 cc.cost=ma[i][j];
128 vec[dd[i][j+1]].push_back(cc);
129 }
130 id++;
131 }
132 }
133 dj(0,id);
134 LL maxx=1e18;
135 for(i=0; i<id; i++)
136 {
137 if(node[i].flag)
138 {
139 if(maxx>d[i])
140 {
141 maxx=d[i];
142 }
143 }
144 }
145 LL akk=0;
146 for(i=0; i<id; i++)
147 {
148 if(maxx==d[i]&&node[i].flag)
149 {
150 akk=akk+sum[i];
151 akk%=mod;
152 }
153 }
154 printf("%lld\n",akk);
155 }
156 return 0;
157 }
158 void dj(int n,int id)
159 {
160 int i,j,k;
161 fill(d,d+10005,1e9);
162 d[n]=ma[0][0];
163 memset(flag,0,sizeof(flag));
164 while(true)
165 {
166 int l=-1;
167 for(i=0; i<id; i++)
168 {
169 if((l==-1||d[i]<d[l])&&flag[i]==false)
170 {
171 l=i;
172 }
173 }
174 if(l==-1)
175 {
176 return ;
177 }
178 flag[l]=true;
179 ss ask=node[l];
180 int x=ask.x;
181 int y=ask.y;
182 int ac=ask.id;
183 if(l==0)
184 {
185 sum[l]=1;
186 }
187 else
188 {
189
190 for(i=0; i<vec[ac].size(); i++)
191 {
192 ss pp=vec[ac][i];
193 if(d[pp.id]+(LL)ma[x][y]==d[l])
194 sum[l]=sum[pp.id]+sum[l];
195 sum[l]%=mod;
196 }
197 }
198 for(i=0; i<vec[ac].size(); i++)
199 {
200 ss pp=vec[ac][i];
201 if(d[pp.id]>d[l]+pp.cost)
202 d[pp.id]=d[l]+pp.cost;
203 }
204 }
205 }

Optimal Symmetric Paths(UVA12295)的更多相关文章

  1. FAQ: Automatic Statistics Collection (文档 ID 1233203.1)

    In this Document   Purpose   Questions and Answers   What kind of statistics do the Automated tasks ...

  2. Contest2073 - 湖南多校对抗赛(2015.04.06)

    Contest2073 - 湖南多校对抗赛(2015.04.06) Problem A: (More) Multiplication Time Limit: 1 Sec  Memory Limit:  ...

  3. Optimal Milking 分类: 图论 POJ 最短路 查找 2015-08-10 10:38 3人阅读 评论(0) 收藏

    Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 13968 Accepted: 5044 Case ...

  4. POJ2112 Optimal Milking (网络流)(Dinic)

                                             Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K T ...

  5. POJ 2112 Optimal Milking (二分+最短路径+网络流)

    POJ  2112 Optimal Milking (二分+最短路径+网络流) Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K To ...

  6. POJ 2112 Optimal Milking (Dinic + Floyd + 二分)

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 19456   Accepted: 6947 ...

  7. POJ2112 Optimal Milking

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 17811   Accepted: 6368 ...

  8. Optimal Milking POJ - 2112 (多重最优匹配+最小费用最大流+最大值最小化 + Floyd)

      Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 19347   Accepted: 690 ...

  9. POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 20262   Accepted: 7230 ...

随机推荐

  1. 前端页面存放token

    //本地缓存,记录token function set(type, value) { localStorage.setItem(type, value); } function get(type) { ...

  2. Android中的性能优化

    由于手机硬件的限制,内存和CPU都无法像pc一样具有超大的内存,Android手机上,过多的使用内存,会容易导致oom,过多的使用CPU资源,会导致手机卡顿,甚至导致anr.我主要是从一下几部分进行优 ...

  3. Kotlin 学习(2)

    属性和字段 1.声明属性 Kotlin中可以使用var关键字声明可变属性,或者用val关键字声明只读属性,属性的类型在后面,变量名在前面,中间加冒号和空格. public class Address ...

  4. soapui pro 5.1.2 的破解方法

    Protection-4.6,和scz.key这两个文件能破解5.1.2的SoapUI 的Pro版本,mac 和 windows均可.1.拷贝Protection-4.6.jar到soapui安装的l ...

  5. Spring Cloud集成RabbitMQ的使用

    同步 or 异步 前言:我们现在有一个用微服务架构模式开发的系统,系统里有一个商品服务和订单服务,且它们都是同步通信的. 目前我们商品服务和订单服务之间的通信方式是同步的,当业务扩大之后,如果还继续使 ...

  6. react-native安卓运行报错:The number of method references in a .dex file cannot exceed 64K.

    错误原因:App里面方法数超过64K解决方法:在android/app/build.gradle中添加implementation 'com.android.support:multidex:1.0. ...

  7. 初步接触Linux命令

    目录 虚拟机快照 1.首先将已经运行的系统关机 2.找到快照 拍摄快照 3.找到克隆 下一步 有几个快照会显示几个 4.克隆完成后 要修改一下IP 不然无法同时运行两个虚拟机系统 系统介绍 1.pin ...

  8. 【JavaWeb】【学习】【过滤器】Filter 的简单应用

    实现效果 在编辑框中输入暗号:如果暗号正确,则跳转到正确页面:如果暗号错误,则跳转到错误界面. [入口界面] [错误界面] [成功界面] [项目结构] JSP文件 本练习有两个jsp页面 页面1:in ...

  9. log4j漏洞的产生原因和解决方案,小白都能看懂!!!!

    核弹级bug Log4j,相信很多人都有所耳闻了,这两天很多读者都在问我关于这个bug的原理等一些问题,今天咱们就专门写一篇文章,一起聊一聊这个核弹级别的bug的产生原理以及怎么防止 产生原因 其实这 ...

  10. HashMap的putAll方法介绍说明

    jdk1.8 使用putAll时,新map中的值仅为旧map值所对应对象的引用,并不会产生新对象. 如下,使用for循环赋值! public void putAll(Map<? extends ...