EZDIJKST – Easy Dijkstra Problem
no tags
Determine the shortest path between the specified vertices in the graph given in the input data.
Hint: You can use Dijkstra’s algorithm.
Hint 2: if you’re a lazy C++ programmer, you can use set and cin/cout (with sync_with_stdio(0)) – it should suffice.
Input
first line – one integer – number of test cases
For each test case the numbers V, K (number of vertices, number of edges) are given,
Then K lines follow, each containing the following numbers separated by a single space:
ai, bi, ci
It means that the graph being described contains an edge from ai to bi,
with a weight of ci.
Below the graph description a line containing a pair of integers A, B is present.
The goal is to find the shortest path from vertex A to vertex B.
All numbers in the input data are integers in the range 0..10000.
Output
For each test case your program should output (in a separate line) a single number C – the length of the shortest path from vertex A to vertex B. In case there is no such path, your program should output a single word “NO” (without quotes)
Example
Input: 3 3 2 1 2 5 2 3 7 1 3 3 3 1 2 4 1 3 7 2 3 1 1 3 3 1 1 2 4 1 3 Output: 12 5 NO
巩固一下dij算法,WA了好几次,原来是有向图。。。看题一定要认真T^T。愈发感觉邻接矩阵版太垃圾了,堆优化大法好
AC代码:
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
const int MAXN = 300005;
#define INF 0x3f3f3f3f
vector<int> e[MAXN];//点
vector<int> w[MAXN];//权
bool vis[MAXN];
LL dis[MAXN];//距离
int pre[MAXN];//记录路径
int n,m;//点数和边数
struct node
{
LL d;//储存距离
int u;//点的标号
bool operator<(const node & rhs) const
{
return d>rhs.d;//距离短的优先
}
};
int dij(int start)
{
priority_queue<node> q;//优先队列
for(int i=1;i<=n;i++)
{
dis[i]=INF;//距离初始化
}
dis[start]=0;//出发点的距离设置为1
memset(vis,0,sizeof(vis));//初始化
node tn;
tn.d=0;//出发点的距离为0
tn.u=start;//出发点为1
q.push(tn);//入队列
while(!q.empty())//队列为空说明已经遍历完了地图
{
node t=q.top();//出队列(最短的出)
q.pop();
int u=t.u;
if(vis[u]) continue;//判断是否访问过
vis[u]=true;//访问后标记
for(int i=0;i<e[u].size();i++)
{
int v = e[u][i];
if(dis[v]>dis[u]+w[u][i])
{
dis[v]=dis[u]+w[u][i];//择优选择
pre[v]=u;//记录路径
tn.d=dis[v];//记录距离
tn.u=v;//设置跳板
q.push(tn);//跳板入队列
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
int cnt=1;
while(t--)
{
int start,end;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
{
e[i].clear();
w[i].clear();
}
int a,b,c;
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&a,&b,&c);
e[a].push_back(b);
w[a].push_back(c); //有向图
}
scanf("%d %d",&start,&end);
dij(start);
if(dis[end]==INF) printf("NO\n");
else printf("%lld\n",dis[end]);
}
return 0;
}