各种细节错误,WA到死。。注意细节!注意细节啊!!!
题目大意:给出N个顶点M条边的无向图,再给出K条边。最多可以用这K条边的一条替换原来的边,求从S到E的最短路。
分析:先求一次从S到E的最短路,再枚举选择K条边中的一条,进行比较,即再分别求两次最短路。(S到所选择边的一点,和另一点到终点E)
代码实现的时候注意几点即可:
1、可以先用Dijkstra,求出S到其它顶点的最短路,与E到其它顶点的最短路。这样在枚举的时候能方便地求出替换之后的最短路长。
2、枚举的时候每一条边需要算两次。(起点和终点交换)
3、输出格式:每相邻两组case之间一个空行。
#include
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 505
struct HeapNode{ //优先队列结点
int d,u;
bool operator < (const HeapNode& rhs) const{
return d>rhs.d;
}
};
struct Edge{ //边
int from,to,dist;
};
struct Dijkstra{
int n,m; //点数和边数
vector edges; //边列表
vector G[maxn]; //每个结点出发的边编号(从0开始)
bool done[maxn]; //是否已永久标号
int d[maxn]; //s到各个点的距离
int p[maxn]; //最短路中的上一条边
void init(int n){
this->n=n;
for(int i=0;i<=n;++i) G[i].clear();//清空邻接表
edges.clear();//清空边表
}
void addEdge(int from,int to,int dist){
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s){ //求s到所有点的最短距离
priority_queue Q;
for(int i=0;i<=n;++i) d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
Q.push((HeapNode){0,s});
while(!Q.empty()){
HeapNode x=Q.top();Q.pop();
int u=x.u;
if(done[u]) continue;
done[u]=1;
for(int i=0;id[u]+e.dist){
d[e.to]=d[u]+e.dist;
p[e.to]=e.from;
Q.push(HeapNode{d[e.to],e.to});
}
}
}
}
void output(int s,int e,vector& path){
int pos=e;
while(1){
path.push_back(pos);
if(pos==s) break;
pos=p[pos];
}
}
};
int main()
{
int i,m,k,n,s,e,x,y,z,flag=0;
while(scanf("%d%d%d",&n,&s,&e)!=EOF){
Dijkstra D,D1;
if(flag) puts("");
else flag=1;
scanf("%d",&m);
D.init(n),D1.init(n);
vectorpath,path2;
while(m--){
scanf("%d%d%d",&x,&y,&z);
D.addEdge(x,y,z);
D.addEdge(y,x,z);
D1.addEdge(x,y,z);
D1.addEdge(y,x,z);
}
D.dijkstra(s),D1.dijkstra(e);
scanf("%d",&k);
int X=-1,Y;
for(i=1;i<=k;++i)
{
scanf("%d%d%d",&x,&y,&z);
if(D.d[x]+z+D1.d[y]0;--i)
printf("%d ",path[i]);
printf("%d\n",e);
puts("Ticket Not Used");
printf("%d\n",D.d[e]);
}
else{
D.output(s,X,path);
for(i=path.size()-1;i>=0;--i)
printf("%d ",path[i]);
D1.output(e,Y,path2);
for(i=0;i