HDU 3191: How Many Paths Are There
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3191
题意:求出次短路的长度和数目
思路:dis[i][0]代表到达的i点的最短路长度,dis[i][1]代表次短路长度;
dp[i][0]代表到达i点的最短路数目,dp[i][1]代表次短路数目;
分四种情况去处理松弛情况
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <utility>
#include <functional>
#pragma comment (linker, "/STACK:1024000000,1024000000")
using namespace std;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
int cnt, head[maxn];
int dis[maxn][2], dp[maxn][2], vis[maxn][2];
struct node
{
int u, d, fl;
node(int _u = 0, int _d = 0, int _fl = 0): u(_u), d(_d), fl(_fl) {}
bool operator < (const node &rhs) const
{
if (d != rhs.d)
return d > rhs.d;
return u > rhs.u;
}
};
struct edge
{
int to, w, nxt;
} e[maxn << 1];
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w)
{
e[cnt].to = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt++;
}
void dijkstra(int s, int t)
{
memset(dis, inf, sizeof(dis));
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
priority_queue <node> que;
dis[s][0] = 0, dp[s][0] = 1;
que.push(node(s, 0, 0));
while (!que.empty())
{
node cur = que.top();
que.pop();
int u = cur.u;
int fl = cur.fl;
if (vis[u][fl]) continue;
vis[u][fl] = true;
for (int i = head[u]; ~i; i = e[i].nxt)
{
node next;
int v = e[i].to;
int w = e[i].w;
if (!vis[v][0] && cur.d + w < dis[v][0])
{
if (dis[v][0] != inf)
{
next.u = v, next.d = dis[v][0], next.fl = 1;
dis[v][1] = dis[v][0];
dp[v][1] = dp[v][0];
que.push(next);
}
dis[v][0] = cur.d + w;
dp[v][0] = dp[u][fl];
next.u = v, next.d = dis[v][0], next.fl = 0;
que.push(next);
}
else if (!vis[v][0] && cur.d + w == dis[v][0])
{
dp[v][0] += dp[u][fl];
}
else if (!vis[v][1] && cur.d + w < dis[v][1])
{
dis[v][1] = cur.d + w;
dp[v][1] = dp[u][fl];
next.u = v, next.d = dis[v][1], next.fl = 1;
que.push(next);
}
else if (!vis[v][1] && cur.d + w == dis[v][1])
{
dp[v][1] += dp[u][fl];
}
}
}
}
int main()
{
int n, m, start, end;
while (~scanf("%d%d%d%d", &n, &m, &start, &end))
{
init();
for (int i = 0; i < m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
dijkstra(start, end);
printf("%d %d\n", dis[end][1], dp[end][1]);
}
return 0;
}
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688
题意:找出最短路和比最短路长1的路径数目之和
思路:和上题差不多,最后多一个判断即可
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <utility>
#include <functional>
#pragma comment (linker, "/STACK:1024000000,1024000000")
using namespace std;
const int maxn = 10010;
const int inf = 0x3f3f3f3f;
int cnt, head[maxn];
int dis[maxn][2], dp[maxn][2], vis[maxn][2];
struct node
{
int u, d, fl;
node(int _u = 0, int _d = 0, int _fl = 0): u(_u), d(_d), fl(_fl) {}
bool operator < (const node &rhs) const
{
if (d != rhs.d)
return d > rhs.d;
return u > rhs.u;
}
};
struct edge
{
int to, w, nxt;
} e[maxn << 1];
void init()
{
cnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w)
{
e[cnt].to = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt++;
}
void dijkstra(int s, int t)
{
memset(dis, inf, sizeof(dis));
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
priority_queue <node> que;
dis[s][0] = 0, dp[s][0] = 1;
que.push(node(s, 0, 0));
while (!que.empty())
{
node cur = que.top();
que.pop();
int u = cur.u;
int fl = cur.fl;
if (vis[u][fl]) continue;
vis[u][fl] = true;
for (int i = head[u]; ~i; i = e[i].nxt)
{
node next;
int v = e[i].to;
int w = e[i].w;
if (!vis[v][0] && cur.d + w < dis[v][0])
{
if (dis[v][0] != inf)
{
next.u = v, next.d = dis[v][0], next.fl = 1;
dis[v][1] = dis[v][0];
dp[v][1] = dp[v][0];
que.push(next);
}
dis[v][0] = cur.d + w;
dp[v][0] = dp[u][fl];
next.u = v, next.d = dis[v][0], next.fl = 0;
que.push(next);
}
else if (!vis[v][0] && cur.d + w == dis[v][0])
{
dp[v][0] += dp[u][fl];
}
else if (!vis[v][1] && cur.d + w < dis[v][1])
{
dis[v][1] = cur.d + w;
dp[v][1] = dp[u][fl];
next.u = v, next.d = dis[v][1], next.fl = 1;
que.push(next);
}
else if (!vis[v][1] && cur.d + w == dis[v][1])
{
dp[v][1] += dp[u][fl];
}
}
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
init();
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
}
int start, end;
scanf("%d%d", &start, &end);
dijkstra(start, end);
if (dis[end][0] + 1 == dis[end][1])
printf("%d\n", dp[end][0] + dp[end][1]);
else
printf("%d\n", dp[end][0]);
}
return 0;
}