#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MID(x,y) ((x+y)>>1)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int sup = (1 << 30);
const int inf = -0x7fffffff;
const int MAXV = 1003;
const int MAXE = 10003;
struct Status{
int v;
int dis;
int type;
friend bool operator < (Status n1, Status n2){
return n2.dis < n1.dis;
}
};
struct node{
int u, v, w;
int next;
}edge[MAXE];
int n, m;
int s, f;
int cnt, head[MAXV];
int dis[MAXV][2], ans[MAXV][2];
bool vis[MAXV][2];
void add(int u, int v, int w){
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt ++;
return ;
}
void init(int n, int m){
mem(head, -1);
for (int i = 0; i <= n; i ++)
dis[i][0] = dis[i][1] = sup;
mem(ans, 0);
mem(vis, 0);
cnt = 0;
}
priority_queue > PQ;
void Dij(int s, int f){
while(!PQ.empty())
PQ.pop();
Status tmp;
dis[s][0] = 0;
ans[s][0] = 1;
tmp.v = s;
tmp.type = 0;
tmp.dis = 0;
PQ.push(tmp);
while(!PQ.empty()){
Status t = PQ.top();
PQ.pop();
if (vis[t.v][t.type]) continue;
vis[t.v][t.type] = 1;
int u = t.v;
int type = t.type;
for (int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
int w = dis[u][type] + edge[i].w;
if (dis[v][0] > w){
dis[v][1] = dis[v][0];
ans[v][1] = ans[v][0];
Status t0;
t0.dis = dis[v][1];
t0.type = 1;
t0.v = v;
PQ.push(t0);
dis[v][0] = w;
ans[v][0] = ans[u][type];
t0.dis = dis[v][0];
t0.type = 0;
t0.v = v;
PQ.push(t0);
}
else if (dis[v][0] == w){
ans[v][0] += ans[u][type];
}
else if (dis[v][1] > w){
dis[v][1] = w;
ans[v][1] = ans[u][type];
Status t0;
t0.dis = dis[v][1];
t0.type = 1;
t0.v = v;
PQ.push(t0);
}
else if (dis[v][1] == w){
ans[v][1] += ans[u][type];
}
}
}
int res = ans[f][0];
if (dis[f][0] == dis[f][1] - 1)
res += ans[f][1];
printf("%d\n", res);
}
int main(){
int te;
scanf("%d", &te);
while (te --){
scanf("%d %d", &n, &m);
init(n, m);
while (m --){
int a, b, l;
scanf("%d %d %d", &a, &b, &l);
add(a, b, l);
}
scanf("%d %d", &s, &f);
Dij(s, f);
}
return 0;
}
,>
POJ 3463 Sightseeing (Dijkstra 次短路)
转载
题目大意:求出图中最短路的条数+比最短路长度大1的路条数。
好题,需要比较深刻地理解Dijkstra的思想。
如果直接求比最短路大1的路,不太好把它转化成一个阶段性、符合最优子结构的模型,求解起来可能会比较麻烦。
所以我们直接求次短路的条数,然后判断下次短路是不是比最短路大1即可。
二维Dijkstra求次短路(k很小时的k短路也适用):
我们知道Dijkstra就是不断地用已经确定最短路的节点(黑色)去松弛未确定的点(白色),用数学归纳法很容易证明这是正确的。它的核心思想就是某个节点的最短路一定是由它前驱节点的最短路扩展来的。那么对于次短路也可以类似的看:一个节点的次短路一定是由它前驱节点的最短路 or 次短路扩展而来的。那么我们就可以把节点分成两层处理:一层处理、存储最短路,另一层处理、存储次短路。这样, 用于记录状态的数组变成了二维, 放进堆中的状态也必须是"二维"的, 这里的"二维"并不是要你开个二维数组, 而是需要在放入堆中的结构体里多加一个标记变量, 用于标识到底是最短路还是次短路, 当然, 用于标记已经确定最短路、次短路的点的closed表同样要变成二维的。循环结束条件是堆为空, 因为要计数, 就必须遍历所有情况.
具体在做状态转移的时候, 拿到当前状态, 扩展下一状态, 设当前状态长度为d, 下一状态最短路和次短路状态分别是d0和d1, 则:
d小于d0, 则d1=d0,d0=d, 计数都重置为所赋的值对应的计数.
d等于d0, 则累加最短路计数.
d小于d1, 则d1=d, 重置次短路计数为所赋的值对应的计数.
d等于d1, 则累加次短路计数.
举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
poj1062——最短路Dijkstra
刚开始理解错题意,导致WA了好久注意点:等级限制不在于前后2人,而在于你交易的
i++ #include #define -
POJ 3463 Sightseeing
DFS dijkstra最短路 次短路
最短路 次短路 #include ide i++ -
[POJ 3463] Sightseeing
[题目链接] http://poj.org/problem?id=3463 [算法] 最短路 [代码]
#include i++ ios #define 最短路 -
Sightseeing(poj 3463)
题意:给出n个点m条单向边,求最短路的道路条数和比最短路大1的道路条数的和。
最短路 #include i++ #define 次短路