您的位置:首页 > 其它

【HDOJ】1688 Sightseeing

2015-03-30 21:11 127 查看
Dijkstra求解次短路径,使用cnt和dis数组记录最小、次小的个数和长度。重写更新操作。

/* 1688 */
#include <iostream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;

#define MAXN 1005
#define INF  0x3f3f3f3f

typedef struct Edge_t {
int v, w;
Edge_t() {}
Edge_t(int u, int ww) {
v = u; w = ww;
}
} Edge_t;

vector<Edge_t> vc[MAXN];
bool visit[MAXN][2];
int dis[MAXN][2];
int cnt[MAXN][2];
int n, m;

void init() {
int i;

for (i=1; i<=n; ++i)
vc[i].clear();
memset(cnt, 0, sizeof(cnt));
}

int dijkstra(int s, int f) {
int i, j, k, tmp, r;
int u, v, w, mmin;
int ret = 0;
Edge_t e;

memset(visit, false, sizeof(visit));
memset(dis, 0x3f, sizeof(dis));
dis[s][0] = 0;
cnt[s][0] = 1;

for (r=0; r<n*2; ++r) {
mmin = INF;
u = -1;
for (j=1; j<=n; ++j) {
if (!visit[j][0] && dis[j][0]<mmin) {
mmin = dis[j][0];
u = j;
k = 0;
} else if  (!visit[j][1] && dis[j][1]<mmin) {
mmin = dis[j][1];
u = j;
k = 1;
}
}
if (u == -1)
break;
visit[u][k] = true;
for (i=0; i<vc[u].size(); ++i) {
e = vc[u][i];
v = e.v;
w = e.w;
tmp = w + dis[u][k];
if (tmp < dis[v][0]) {
dis[v][1] = dis[v][0];
cnt[v][1] = cnt[v][0];
dis[v][0] = tmp;
cnt[v][0] = cnt[u][k];
} else if (tmp == dis[v][0]) {
cnt[v][0] += cnt[u][k];
} else if (tmp < dis[v][1]) {
dis[v][1] = tmp;
cnt[v][1] = cnt[u][k];
} else if (tmp == dis[v][1]) {
cnt[v][1] += cnt[u][k];
}
}
}

ret += cnt[f][0];
if (dis[f][0]+1 == dis[f][1])
ret += cnt[f][1];
return ret;
}

int main() {
int t;
int i, j, k;
Edge_t e;

#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

scanf("%d", &t);
while (t--) {
scanf("%d %d", &n, &m);
init();
while (m--) {
scanf("%d %d %d", &i, &e.v, &e.w);
vc[i].push_back(e);
}
scanf("%d %d", &i, &j);
k = dijkstra(i, j);
printf("%d\n", k);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: