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;
}
题意:给出一张有向图,求从起点到终点的最短路条数和比最短路长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;
}
相关文章推荐
- 通过POJ 3463 Sightseeing(dijkstra)彻底理解优先队列优化的dijkstra算法
- POJ 3463 Sightseeing (第k短路)
- Poj 3463 Sightseeing
- poj 3463 Sightseeing(最短路和次短路)
- POJ 3463 Sightseeing(次短路)
- POJ 3463 Sightseeing
- POJ 3463 Sightseeing (Dijkstra 次短路)
- POJ 3463 Sightseeing(次短路)转自'wind
- POJ --- 3463 or HDU 1688 Sightseeing 【次短路 + 最短路 + Dij】
- POJ 3463 Sightseeing
- POJ 3463 Sightseeing 次短路
- POJ 3463 Sightseeing
- poj 3463 Sightseeing
- POJ 3463 Sightseeing (Dijkstra 次短路)
- poj 3463 Sightseeing(次短路+条数统计)
- POJ---3463 Sightseeing[Dijkstra()求最短路和次短路条数][好题]
- poj 3463 Sightseeing 最短路和次短路计数
- POJ 3463 Sightseeing (最短路&次短路条数问题)
- POJ 3463:Sightseeing
- POJ 3463 Sightseeing (次短路,Dijkstra拓展)