C++ Dijkstra'中的优先级队列;s算法
这是我的Dijkstra算法代码:C++ Dijkstra'中的优先级队列;s算法,c++,algorithm,dijkstra,C++,Algorithm,Dijkstra,这是我的Dijkstra算法代码: #include<iostream> #include<cstdio> #include<vector> #include<queue> #define pp pair<int,int> using namespace std; struct pri { int operator() (const pair<int,int>&p1,const pair<int,in
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#define pp pair<int,int>
using namespace std;
struct pri
{
int operator() (const pair<int,int>&p1,const pair<int,int>&p2)
{
return p1.second<p2.second;
}
}p;
int main()
{
priority_queue<pp,vector<pp>,pri> q;
int n;
cin>>n;
vector<pp> g[n+1];
int e,u,v,w,i;
cin>>e;
for(i=0;i<e;i++)
{
cin>>u>>v>>w;
g[u].push_back(pp(v,w));
g[v].push_back(pp(u,w));
}
int s;
cin>>s;
int d[n+1];
for(i=1;i<=n;i++)
d[i]=999;
d[s]=0;
q.push(pp(s,d[s]));
while(!q.empty())
{
u=q.top().first;
q.pop();
int size=g[u].size();
for(int i=0;i<size;i++)
{
v=g[u][i].first;
w=g[u][i].second;
cout<<u<<" "<<" "<<w<<endl;
if(d[v]>d[u]+w)
{
d[v]=d[u]+w;
q.push(pp(v,d[v]));
}
}
}
for(i=1;i<=n;i++)
printf("node %d,min weight=%d\n",i,d[i]);
return 0;
}
#包括
#包括
#包括
#包括
#定义pp对
使用名称空间std;
结构优先级
{
int运算符()(常量对和p1、常量对和p2)
{
返回p1.second>n;
向量g[n+1];
int e,u,v,w,i;
cin>>e;
对于(i=0;i>u>>v>>w;
g[u]。推回(pp(v,w));
g[v].推回(pp(u,w));
}
int-s;
cin>>s;
int d[n+1];
对于(i=1;i当声明变量(包括函数参数)时,&
将变量标记为引用。对某些类型的参数使用引用是非常基本和常见的事情,部分原因是它传递参数而不创建副本(例如,对于std::vector
)它还允许在函数中以输出参数的形式更改非常量引用
至于在这样的结构中使用operator()
,它会生成结构的实例,换句话说,就是可以像函数一样调用的对象。struct pri{
struct pri {
int operator() (const pair<int,int>&p1,const pair<int,int>&p2)
{
return p1.second<p2.second;
}
}p;
int运算符()(常量对和p1、常量对和p2)
{
返回p1。第二个我想你的问题是关于行优先级\u队列q;
这声明了priority\u queue
类型的变量q
,priority\u queue
定义为
template<class T,
class Container = vector<T>,
class Compare = less<typename Container::value_type> >
class priority_queue;
模板
类优先级队列;
因此,pp
是元素的类型,vector
是容器(与默认值相同),pri
是用于比较队列中项目的函数对象(compare
).Thepriority_queue
使用Compare
对其元素进行排序。如果无法直接比较元素,或者默认值不合适,则您可以提供自己的元素。在这种情况下,元素将按每个元素对中的第二个成员排序,与其他答案基本相同,JU再详细一点——操作符()代码定义了优先级队列应该如何进行比较以确定队列中的项目优先级。使用这种类型的框架,您可以定义优先级队列来存储任何类型的对象,并且优先级队列可以根据您想要对对象进行的任何自定义排序进行排序。我认为您可以使用比较功能写错了
int operator() (const pair<int,int>&p1,const pair<int,int>&p2)
{
return p1.second<p2.second;
}
(通过使用您的代码解决问题,我花了很长时间才发现我的程序的结果总是与正确的结果不同。)
(顺便说一句,在Dijkstra算法本身中,我认为一旦一个节点作为最小的节点弹出,就没有必要再次弹出它并更新所有连接到它的节点。这可以节省很多时间。)我重构了这段代码,并与hackerrank进行了检查
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <vector>
#include <deque>
#include <set>
#include <limits>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
struct pri
{
typedef pair<int,int> pp;
typedef deque<pri::pp > list;
typedef vector< pri::list > graph;
int operator() (pp&p1,const pp&p2)
{
return p1.second>p2.second;
}
typedef priority_queue< pri::pp, pri::list, pri > queue;
};
static int f1(const int x){ return x==std::numeric_limits<int>().max()?-1:x; }
int main()
{
int t;
cin>>t;
while(t--){
int n,e;
cin>>n>>e;
pri::graph g(n+1);
for(int i(0);i<e;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(pri::pp(v,w));
g[v].push_back(pri::pp(u,w));
}
vector<int> d(n+1,std::numeric_limits<int>().max());
int s; cin>>s;
d[s]=0;
pri::queue q;
q.push(pri::pp(s,d[s]));
set<int> vs;
while(!q.empty()) {
const int u(q.top().first);
const pri::list& gu(g[u]);
q.pop();
vs.insert(u);
for( pri::list::const_iterator i(gu.begin()); i != gu.end(); ++i ) {
const int v(i->first), w(i->second);
if( vs.find(v)==vs.end() ){
// cout<<u<<" "<<v<<" "<<w<<endl;
if( d[v]>d[u]+w ) {
d[v]=d[u]+w;
q.push(pri::pp(v,d[v]));
}
}
}
}
copy_if(d.begin()+1,d.end(),d.begin(),std::bind2nd(std::not_equal_to<int>(),0));
transform(d.begin(),d.end()-2,ostream_iterator<int>(cout," "),f1);
cout<<endl;
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
结构优先级
{
typedef对pp;
类型定义定义列表;
typedef向量图形;
int运算符()(pp和p1,常量pp和p2)
{
返回p1.second>p2.second;
}
typedef priority_queuequeue;
};
静态int f1(const int x){return x==std::numeric_limits().max()?-1:x;}
int main()
{
int t;
cin>>t;
而(t--){
int n,e;
cin>>n>>e;
pri::图g(n+1);
对于(inti(0);i>u>>v>>w;
g[u].push_-back(pri::pp(v,w));
g[v].推回(pri::pp(u,w));
}
向量d(n+1,std::numeric_limits().max());
int-s;cin>>s;
d[s]=0;
pri::队列q;
q、 push(pri::pp(s,d[s]);
设置vs;
而(!q.empty()){
常数int u(q.top().first);
常量pri::list&gu(g[u]);
q、 pop();
vs.insert(u);
for(pri::list::const_迭代器i(gu.begin());i!=gu.end();++i){
常数INTV(i->第一),w(i->第二);
如果(vs.find(v)=vs.end()){
//cout请正确缩进。它是一个结构
或类
,实现公共运算符()()
,以便类的实例可以像函数一样使用。请参阅
int operator() (const pair<int,int>&p1,const pair<int,int>&p2)
{
return p1.second<p2.second;
}
int operator() (const pair<int,int>&p1,const pair<int,int>&p2)
{
return p1.second>p2.second;
}
p1.second>p2.second
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
#include <vector>
#include <deque>
#include <set>
#include <limits>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
struct pri
{
typedef pair<int,int> pp;
typedef deque<pri::pp > list;
typedef vector< pri::list > graph;
int operator() (pp&p1,const pp&p2)
{
return p1.second>p2.second;
}
typedef priority_queue< pri::pp, pri::list, pri > queue;
};
static int f1(const int x){ return x==std::numeric_limits<int>().max()?-1:x; }
int main()
{
int t;
cin>>t;
while(t--){
int n,e;
cin>>n>>e;
pri::graph g(n+1);
for(int i(0);i<e;i++){
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(pri::pp(v,w));
g[v].push_back(pri::pp(u,w));
}
vector<int> d(n+1,std::numeric_limits<int>().max());
int s; cin>>s;
d[s]=0;
pri::queue q;
q.push(pri::pp(s,d[s]));
set<int> vs;
while(!q.empty()) {
const int u(q.top().first);
const pri::list& gu(g[u]);
q.pop();
vs.insert(u);
for( pri::list::const_iterator i(gu.begin()); i != gu.end(); ++i ) {
const int v(i->first), w(i->second);
if( vs.find(v)==vs.end() ){
// cout<<u<<" "<<v<<" "<<w<<endl;
if( d[v]>d[u]+w ) {
d[v]=d[u]+w;
q.push(pri::pp(v,d[v]));
}
}
}
}
copy_if(d.begin()+1,d.end(),d.begin(),std::bind2nd(std::not_equal_to<int>(),0));
transform(d.begin(),d.end()-2,ostream_iterator<int>(cout," "),f1);
cout<<endl;
}
return 0;
}