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. sqlalchemy模块的基本使用

    Python中SQLAlchemy模块通过建立orm来对数据库进行操作 1. 建表 方式1 # -*- coding:utf-8 -*- # Author:Wong Du from sqlalchem ...

  2. 字符串String的trim()方法

    用来删除字符串两端的空白字符并返回,trim方法并不影响原来的字符串本身,它返回的是一个新的字符串 String a = "  Hello World  "; String b = ...

  3. flink-----实时项目---day04-------1. 案例:统计点击、参与某个活动的人数和次数 2. 活动指标多维度统计(自定义redisSink)

    1. 案例 用户ID,活动ID,时间,事件类型,省份 u001,A1,2019-09-02 10:10:11,1,北京市 u001,A1,2019-09-02 14:10:11,1,北京市 u001, ...

  4. 【2021赣网杯web(一)】gwb-web-easypop

    源码分析 <?php error_reporting(0); highlight_file(__FILE__); $pwd=getcwd(); class func { public $mod1 ...

  5. mysql_取分组后的前几行值

    --方法一: select a.id,a.SName,a.ClsNo,a.Score from Table1 a left join Table1 b on a.ClsNo=b.ClsNo and a ...

  6. Activity 详解

    1.活动的生命周期 1.1.返回栈 Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈.栈是一种先进后出的数据结构,在默认情况下,每当我们启 ...

  7. 【编程思想】【设计模式】【行为模式Behavioral】registry

    Python版 https://github.com/faif/python-patterns/blob/master/behavioral/registry.py #!/usr/bin/env py ...

  8. 项目cobbler+lamp+vsftp+nfs+数据实时同步(inotify+rsync)

    先配置好epel源 [root@node3 ~]#yum install epel-release -y 关闭防火墙和selinux [root@node3 ~]#iptables -F [root@ ...

  9. VueAPI 2 (生命周期钩子函数)

    所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算.这意味着你不能使用箭头函数来定义一个生命周期方法. beforeCreate 在实例初始化之后,此时还不 ...

  10. 【C/C++】拔河比赛/分组/招商银行

    题目:小Z组织训练营同学进行一次拔河比赛,要从n(2≤n≤60,000)个同学中选出两组同学参加(两组人数可能不同).对每组同学而言,如果人数超过1人,那么要求该组内的任意两个同学的体重之差的绝对值不 ...