博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 12295 Optimal Symmetric Paths
阅读量:5230 次
发布时间:2019-06-14

本文共 3200 字,大约阅读时间需要 10 分钟。

UVA_12295

    首先我们可以把线的两边对折,这样就变成了半个矩阵,同时问题就转化成了从左上角到折线的位置的最短路径的条数有多少。

    首先,我们可以用SPFA求单源最短路,这样起点到每个点的最短路就都有了。之后为了能够算出路径的条数,我们可以从起点开始,每次取栈中d[]的值最小的点出栈,然后按最短路径的走向向周围的点拓展,并将拓展成功的点入栈。

    最后,统计折线上的最短路的最小值,并把所有符合要求的路径的条数相加即可。

    这个题目用dij及优先级队列做会更简单、高效,等学完dij之后再回头做下这个题目。

#include
#include
#include
#define MAXN 110 #define MAXD 10010 #define INF 1000000000 #define MOD 1000000009 int N, a[MAXN][MAXN]; long long int f[MAXD]; int q[MAXD], inq[MAXD], d[MAXD], min; int dx[] = {-1, 1, 0, 0}, dy[] = {
0, 0, -1, 1}; int cmp(const void *_p, const void *_q) {
int *p = (int *)_p; int *q = (int *)_q; return d[*q] - d[*p]; } int init() {
int i, j; scanf("%d", &N); if(!N) return 0; for(i = 0; i < N; i ++) for(j = 0; j < N; j ++) scanf("%d", &a[i][j]); for(i = 0; i < N; i ++) for(j = 0; j < N - i - 1; j ++) a[i][j] += a[N - 1 - j][N - 1 - i]; return 1; } void SPFA() {
int i, j, k, z, newz, x, y, newx, newy, front, rear; for(i = 0; i < MAXD; i ++) d[i] = INF; d[0] = a[0][0]; memset(inq, 0, sizeof(inq)); front = rear = 0; q[rear ++] = 0; while(front != rear) {
z = q[front ++]; if(front > N * N) front = 0; inq[z] = 0; x = z / N; y = z % N; if(x + y == N - 1) continue; for(i = 0; i < 4; i ++) {
newx = x + dx[i]; newy = y + dy[i]; if(newx >= 0 && newx < N && newy >= 0 && newy < N) {
newz = newx * N + newy; if(d[z] + a[newx][newy] < d[newz]) {
d[newz] = d[z] + a[newx][newy]; if(!inq[newz]) {
q[rear ++] = newz; if(rear > N * N) rear = 0; inq[newz] = 1; } } } } } } void DP() {
int i, j, k, top, z, x, y, newx, newy, newz; top = 0; memset(f, 0, sizeof(f)); memset(inq, 0, sizeof(inq)); f[0] = 1; inq[0] = 1; q[top ++] = 0; while(top) {
z = q[-- top]; x = z / N, y = z % N; if(x + y == N - 1) continue; for(i = 0; i < 4; i ++) {
newx = x + dx[i]; newy = y + dy[i]; if(newx >= 0 && newx < N && newy >= 0 && newy < N) {
newz = newx * N + newy; if(d[newz] == d[z] + a[newx][newy]) {
f[newz] = (f[newz] + f[z]) % MOD; if(!inq[newz]) {
inq[newz] = 1; q[top ++] = newz; } } } } qsort(q, top, sizeof(q[0]), cmp); } } void solve() {
int i, j, k; long long int ans; SPFA(); DP(); min = INF; for(i = 0; i < N; i ++) if(d[i * N + N - 1 - i] < min) min = d[i * N + N - 1 - i]; ans = 0; for(i = 0; i < N; i ++) if(d[i * N + N - 1 - i] == min) ans = (ans + f[i * N + N - 1 - i]) % MOD; printf("%lld\n", ans); } int main() {
while(init()) {
solve(); } return 0; }

转载于:https://www.cnblogs.com/staginner/archive/2011/11/05/2237176.html

你可能感兴趣的文章
721. Accounts Merge
查看>>
OpenCv-Python 图像处理基本操作
查看>>
「Unity」委托 将方法作为参数传递
查看>>
重置GNOME-TERMINAL
查看>>
redis哨兵集群、docker入门
查看>>
hihoCoder 1233 : Boxes(盒子)
查看>>
团队的绩效评估计划
查看>>
oracle中anyData数据类型的使用实例
查看>>
C++对vector里面的元素排序及取任意重叠区间
查看>>
软件测试——性能测试总结
查看>>
12.4站立会议
查看>>
泰勒展开,傅里叶变换,拉普拉斯变换和Z变换的物理意义
查看>>
Java Concurrentmodificationexception异常原因和解决方法
查看>>
Python 面向对象(其四)
查看>>
客户端访问浏览器的流程
查看>>
codeforces水题100道 第二十二题 Codeforces Beta Round #89 (Div. 2) A. String Task (strings)
查看>>
c++||template
查看>>
[BZOJ 5323][Jxoi2018]游戏
查看>>
编程面试的10大算法概念汇总
查看>>
Vue
查看>>