您的位置:首页 > 其它

poj 3463 Sightseeing

2018-03-10 16:29 253 查看
题目:Sightseeing

题意:给出一张有向图,求从起点到终点的最短路条数和比最短路长1的路径条数和。

思路:
dijkstra求出最短路和次短路以及条数。如果次短路只比最短路长1,输出条数和。否则仅输出最短路的条数。
参考这位dalao的代码。

代码:#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;

#define maxn 10000

int n,m;
int s,e;

struct Edge {
int x,y,c;
Edge(int xx=0,int yy=0,int cc=0) {
x=xx,y=yy,c=cc;
}
bool operator < (const Edge& oth) const {
return y>oth.y||(y==oth.y&&x<oth.x);
}
};

vector<Edge> a[maxn+5];

int dist1[maxn+5],dist2[maxn+5]; //最、次短路
int cnt[maxn+5][3]; //最、次短路的条数

bool c[maxn+5][3];
priority_queue<Edge> p;

void init() { //初始化
for(int i=1; i<=maxn; i++) {
a[i].clear();
dist1[i]=dist2[i]=(1<<29);
}
memset(c,0,sizeof(c));
memset(cnt,0,sizeof(cnt));
priority_queue<Edge> emp;
p=emp;
}

void dijkstra() { //dijkstra求最短路和次短路
dist1[s]=0,cnt[s][1]=1;
p.push(Edge(s,0,1));

while(!p.empty()) {
Edge x=p.top();
p.pop();
if(c[x.x][x.c]) continue;
c[x.x][x.c]=true;

for(int i=0; i<a[x.x].size(); i++) {
if(dist1[a[x.x][i].x]>x.y+a[x.x][i].y) { //更新最短路
dist2[a[x.x][i].x]=dist1[a[x.x][i].x];
cnt[a[x.x][i].x][2]=cnt[a[x.x][i].x][1];
dist1[a[x.x][i].x]=x.y+a[x.x][i].y;
cnt[a[x.x][i].x][1]=cnt[x.x][x.c];
p.push(Edge(a[x.x][i].x,dist1[a[x.x][i].x],1));
p.push(Edge(a[x.x][i].x,dist2[a[x.x][i].x],2)); //注意!由于这里也更新了次短路,所以不能忘记这一行
} else if(dist1[a[x.x][i].x]==x.y+a[x.x][i].y) { //更新最短路的条数
cnt[a[x.x][i].x][1]+=cnt[x.x][x.c];
} else if(dist2[a[x.x][i].x]>x.y+a[x.x][i].y) { //更新次短路
dist2[a[x.x][i].x]=x.y+a[x.x][i].y;
cnt[a[x.x][i].x][2]=cnt[x.x][x.c];
p.push(Edge(a[x.x][i].x,dist2[a[x.x][i].x],2));
} else if(dist2[a[x.x][i].x]==x.y+a[x.x][i].y) { //更新次短路的条数
cnt[a[x.x][i].x][2]+=cnt[x.x][x.c];
}
}
}
}

void readin() { //读入
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
a[x].push_back(Edge(y,z));
}
scanf("%d%d",&s,&e);
}

void print() { //输出asd
int ans=cnt[e][1];
if(dist1[e]+1==dist2[e]) ans+=cnt[e][2]; //仅当最短路只比次短路小1时才有效
printf("%d\n",ans);
}

int main() {
int T;
scanf("%d",&T);

while(T--) {
init();
readin();
dijkstra();
print();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息