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 }