HDU 1688

分析

一个图论题,其实没什么特别难的点。
英文题首先我们要读懂题意
这道题大意就是求最短路的条数,如果次短路和最短路只差1,那么也把次短路的条数加上。
求最短路应该都会求,一个Dij就完了,那么条数怎么办。
之前也做过类似的题,如果要更新最短路,那么更新完最短路后,次短路就会更新为原来的最短路,以此类推。
然后还有一些小细节注意一下,vis数组应该分最短路和次短路,两个都更新。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int lqs=1314;
using namespace std;
struct Edge{
	int to,nxt,val;
}e[lqs*520];
struct Node{
	int id,w,type;
	Node(){}
	Node(int a,int b,int c){
		id=a;w=b;type=c;
	}
	bool operator < (const Node&A)const {
		return w>A.w;
	}
};
int h[lqs],idx;
void Ins(int a,int b,int c){
	e[++idx].to=b;e[idx].nxt=h[a];
	h[a]=idx;e[idx].val=c;
}
int dis[lqs][2],ways[lqs][2],vis[lqs][2];
void dij(int s){
	dis[s][1]=0;ways[s][1]=1;
	priority_queue<Node > q;
	q.push(Node(s,0,1));
	while(!q.empty()){
		Node u=q.top();q.pop();
		if(vis[u.id][u.type])continue;
		vis[u.id][u.type]=1;
		for(int i=h[u.id];i;i=e[i].nxt){
			int v=e[i].to,w=e[i].val;
			if(dis[v][1]>dis[u.id][u.type]+w){
				dis[v][0]=dis[v][1];
				ways[v][0]=ways[v][1];
				dis[v][1]=dis[u.id][u.type]+w;
				ways[v][1]=ways[u.id][u.type];
				q.push(Node(v,dis[v][1],1));
				q.push(Node(v,dis[v][0],0));
			}else if(dis[v][1]==dis[u.id][u.type]+w){
				ways[v][1]+=ways[u.id][u.type];
			}
			else if(dis[v][0]>dis[u.id][u.type]+w){
			 	dis[v][0]=dis[u.id][u.type]+w;
			 	ways[v][0]=ways[u.id][u.type];
			 	q.push(Node(v,dis[v][0],0));
			}else if(dis[v][0]==dis[u.id][u.type]+w){
			 	ways[v][0]+=ways[u.id][u.type];
			}
		}
	}
}
void init(int n){
	for(int i=1;i<=n;++i){
		dis[i][1]=dis[i][0]=0x3f3f3f3f;
		ways[i][1]=ways[i][0]=0;
		vis[i][1]=vis[i][0]=0;h[i]=0;
	}
	idx=0;
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n,m;
		scanf("%d%d",&n,&m);
		init(n);
		for(int i=1;i<=m;++i){
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			Ins(a,b,c);
		}
		int s,t;
		scanf("%d%d",&s,&t);
		dij(s);
		if(dis[t][1]==dis[t][0]-1)
			ways[t][1]+=ways[t][0];
		printf("%d
",ways[t][1]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/anyixing-fly/p/12945990.html