Dijkstra算法主要用来解决边权为正时的单源最短路问题(就是从一个源点出发,到所有结点的最短路),同时适用于有向图和无向图
略
时间复杂度为O(n^2)
没有堆优化的代码
时间复杂度为O(n^2)
const int INF=1<<30;
int v[maxn];
int d[maxn];
int w[maxn][maxn];
memset(v,0,sizeof(v));
for(int i=0;i
进行堆优化的代码
时间复杂度为O(mlogn)
struct edge{ //储存边
int from,to,w;
edge(int u,int v,int d):from(u),to(v),w(d){}
}
struct node{ //用来结合优先队列使用
int d,u;
bool operator < (const node &rhs) const {
return d>rhs.d;
}
}
vectoredges;
vectorg[maxn];
int d[maxn];
void addedge(int from ,int to,int wei){ //加边函数,若为无向边,则调用addedge(u,v,w);addedge(v,u,w);各一次
edges.push_back(edge(from,to,wei));
m=edges.size();
g[from].push_back(m-1);
}
void dij(){
priority_queue q;
for(int i=0;i<=t;i++) d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
q.push((node){0,s});
while(!q.empty()){
node x=q.top();q.pop();
int u=x.u;
if(done[u]) continue;
done[u]=1;
for(int i=head[u];~i;i=nxt[i]){
if(d[to[i]]>d[u]+dis[i]){ //松弛操作
d[to[i]]=d[u]+dis[i];
q.push((node){d[to[i]],dis[i]});
}
}
}
}
void print(int t){ //s为源点,t为终点
printf("%d ",t);
if(s==t) return;
for(int i=0;i
题目 HDU - 6166
AC代码
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=100005;
const long long INF=0x3f3f3f3f3f3f3f3f;
int tot,k;
int head[maxn],done[maxn],a[maxn],mark[maxn];
long long d[maxn];
struct edge{
int to,next;
long long dis;
}edges[maxn];
struct node{
int u;
long long d;
bool operator < (const node& rhs) const{
return d>rhs.d;
}
};
priority_queueq;
void addedge(int from,int to,long long w){
edges[tot].to=to;
edges[tot].dis=w;
edges[tot].next=head[from];
head[from]=tot++;
}
long long dij(){
while(!q.empty()){
struct node x=q.top();q.pop();
if(mark[x.u]) return x.d;
if(done[x.u]) continue;
done[x.u]=1;
for(int i=head[x.u];~i;i=edges[i].next){
if(d[edges[i].to]>d[x.u]+edges[i].dis){
d[edges[i].to]=d[x.u]+edges[i].dis;
q.push(node{edges[i].to,d[edges[i].to]});
}
}
}
return INF;
}
void init(){
memset(done,0,sizeof(done));
memset(mark,0,sizeof(mark));
memset(d,0x3f3f3f3f3f3f3f3f,sizeof(d));
while(!q.empty()) q.pop();
}
int main(){
int t,n,m,kase=0;
int u,v;
long long w;
scanf("%d",&t);
while(t--){
tot=0;
memset(head,-1,sizeof(head));
long long ans=INF;
scanf("%d%d",&n,&m);
for(int i=0;i
这道题有多种思路。下面写的思路是设置一个古城中心,各个古城到古城中心设一条长度为x/2的无向边
ac代码
#include
#include
#include
#include
#include
#include
#include
#include
如有错误,欢迎指出