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. C#判断是否有中文

    using System.Text.RegularExpressions; Regex reg = new Regex(@"[\u4e00-\u9fa5]"); if (reg.I ...

  2. 为什么重写equals必须重写hashCode

    目录 equals常见面试题 为什么要重写equals 重写equals不重写hashCode会存在什么问题 总结 equals常见面试题 在开始聊之前,我们先看几个常见的面试题,看看你能不能都回答上 ...

  3. 【Netty】最透彻的Netty原理架构解析

    这可能是目前最透彻的Netty原理架构解析 本文基于 Netty 4.1 展开介绍相关理论模型,使用场景,基本组件.整体架构,知其然且知其所以然,希望给大家在实际开发实践.学习开源项目方面提供参考. ...

  4. ps精修

    1.磨皮方法: a,, 添加高斯模糊后,按住alt键新建图层蒙版,设置前景色为白色,用画笔在脸上雀斑的位置涂抹,注意脸轮廓位置不要涂抹.最后添加曲线提亮 b. 添加蒙尘和划痕后,后面上面的一样

  5. cordova配置与开发

    1.环境配置 1.1.安装ant 从 apache官网 下载ant,安装并配置,将ant.bat所在目录加到path环境变量,如c:\apache-ant\bin\.在cmd中运行以下语句如不报错即可 ...

  6. OpenStack之之一: 快速添加计算节点

    根据需求创建脚本,可以快速添加节点#:初始化node节点 [root@node2 ~]# systemctl disable NetworkManager [root@node2 ~]# vim /e ...

  7. mysql与clickhouse的字段类型对应表

  8. shell条件测试语句实例-测试apache是否开启

    终于理解了shell条件测试语句"!="和"-n"的用法区别,于是有了如下的shell脚本,做为练习. 第一种方法:测试apache是否开启?字符串测试 #!/ ...

  9. SQL 父子表,显示表中每条记录所在层级

    1.sqlserer 中有一张父子关系表,表结构如下: CREATE TABLE [dbo].[testparent]( [ID] [int] IDENTITY(1,1) NOT NULL, [nam ...

  10. MFC入门示例之树控件(CTreeControl)

    1 //增加按钮 2 void CMFCApplication8Dlg::OnBnClickedButtonAdd() 3 { 4 //树中添加节点 5 CString strText; 6 GetD ...