Optimal Symmetric Paths(UVA12295)
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 ( 2n
100). 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)的更多相关文章
- FAQ: Automatic Statistics Collection (文档 ID 1233203.1)
In this Document Purpose Questions and Answers What kind of statistics do the Automated tasks ...
- Contest2073 - 湖南多校对抗赛(2015.04.06)
Contest2073 - 湖南多校对抗赛(2015.04.06) Problem A: (More) Multiplication Time Limit: 1 Sec Memory Limit: ...
- Optimal Milking 分类: 图论 POJ 最短路 查找 2015-08-10 10:38 3人阅读 评论(0) 收藏
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 13968 Accepted: 5044 Case ...
- POJ2112 Optimal Milking (网络流)(Dinic)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K T ...
- POJ 2112 Optimal Milking (二分+最短路径+网络流)
POJ 2112 Optimal Milking (二分+最短路径+网络流) Optimal Milking Time Limit: 2000MS Memory Limit: 30000K To ...
- POJ 2112 Optimal Milking (Dinic + Floyd + 二分)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 19456 Accepted: 6947 ...
- POJ2112 Optimal Milking
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 17811 Accepted: 6368 ...
- Optimal Milking POJ - 2112 (多重最优匹配+最小费用最大流+最大值最小化 + Floyd)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 19347 Accepted: 690 ...
- POJ2112:Optimal Milking(Floyd+二分图多重匹配+二分)
Optimal Milking Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 20262 Accepted: 7230 ...
随机推荐
- vim文本编辑器的基本使用
vim文本编辑器的基本使用 1. vi和vim的区别和联系 可以说vim是vi的增强版,在使用vim编辑文本时,可以根据字体颜色来判断编写程序的正确性. 2. vim文本编辑器的常用命令 1. 编辑指 ...
- C语言中的main函数的参数解析
main()函数既可以是无参函数,也可以是有参的函数.对于有参的形式来说,就需要向其传递参数.但是其它任何函数均不能调用main()函数.当然也同样无法向main()函数传递,只能由程序之外传递而来. ...
- Learning Spark中文版--第四章--使用键值对(1)
本章介绍了如何使用键值对RDD,Spark中很多操作都基于此数据类型.键值对RDD通常在聚合操作中使用,而且我们经常做一些初始的ETL(extract(提取),transform(转换)和load ...
- Spark 广播变量和累加器
Spark 的一个核心功能是创建两种特殊类型的变量:广播变量和累加器 广播变量(groadcast varible)为只读变量,它有运行SparkContext的驱动程序创建后发送给参与计算的节点.对 ...
- 13个酷炫的JavaScript一行程序
1. 获得一个随机的布尔值(true/false) const randomBoolean = () => Math.random() >= 0.5; console.log(random ...
- Linux 设置时区
一.查看和修改Linux的时区 1. 查看当前时区命令 : "date -R" 2. 修改设置Linux服务器时区方法 A命令 : "tzselect" 方法 ...
- HelloWorldMBean
package mbeanTest; public interface HelloWorldMBean { public String getHello(); public void setHello ...
- list通过比较器进行排序
Collections.sort(dataList,new Comparator<BaseTransitData>(){ public int compare(Bas ...
- linux网络相关命令之脚本和centos启动流程
nice 功用:设置优先权,可以改变程序执行的优先权等级.等级的范围从-19(最高优先级)到20(最低优先级).优先级为操作系统决定cpu分配的参数,优先级越高,所可能获得的 cpu时间越长. 语法: ...
- @PropertySource配置的用法
功能 加载指定的属性文件(*.properties)到 Spring 的 Environment 中.可以配合 @Value 和@ConfigurationProperties 使用. @Proper ...