題目:dijkstra求最短路徑
#include#include
#includeusing namespace std;
const int N=510,INF=0x3f3f3f3f;
int g[N][N];
int dist[N];
int st[N];
int n,m;
int dijkstra()
{memset(dist,INF,sizeof dist);
dist[1]=0;
for(int i=0;i int t=-1;
for(int j=1;j<=n;j++)
{ if(st[j]==0&&(t==-1||dist[t]>dist[j]))
t=j;
}
st[t]=1;
for(int j=1;j<=n;j++)
{ if(st[j]==0)
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
if(dist[n]==0x3f3f3f3f)
return -1;
else
return dist[n];
}
int main()
{cin>>n>>m;
memset(g,INF,sizeof g);
for(int i=0;iint x,y,z;
cin>>x>>y>>z;
g[x][y]=min(g[x][y],z);
}
cout<
2.Dijkstra優(yōu)化在記錄優(yōu)化之前,先要知道使用一個(gè)類(lèi)模板—優(yōu)先隊(duì)列(stl):
STL中定義優(yōu)先隊(duì)列的模板類(lèi)為priority_queue,其定義如下:
template
模板里面有三個(gè)參數(shù),第一個(gè)為元素的類(lèi)型,第二個(gè)為所使用的容器(vector或deque),第三個(gè)為一個(gè)比較的規(guī)則,決定是大優(yōu)先隊(duì)列還是最小優(yōu)先隊(duì)列,默認(rèn)的less為大優(yōu)先隊(duì)列,實(shí)現(xiàn)方式是大堆,greater為最小優(yōu)先隊(duì)列,實(shí)現(xiàn)方式是最小堆,結(jié)構(gòu)都是二叉樹(shù)。
大根堆就是根節(jié)點(diǎn)大,小根堆就是根節(jié)點(diǎn)最小。
#include//c++標(biāo)準(zhǔn)頭文件,可以使用cout,cin等標(biāo)準(zhǔn)庫(kù)函數(shù)
#include//使用priority_queue時(shí)需要的頭文件
using namespace std;//命名空間,防止重名給程序帶來(lái)各種隱患,使用cin,cout,stack,map,set,vector,queue時(shí)都要使用
struct test {//定義一個(gè)結(jié)構(gòu)體test
int val;
test(int v) {//構(gòu)造函數(shù)
this->val = v;
}
bool operator >(const test t)const {//重載運(yùn)算符>if (val >t.val)
return true;
else
return false;
}
bool operator< (const test t)const {//重載運(yùn)算符
return val< t.val;
}
};
int main() {priority_queue, less>q1;//定義一個(gè)大頂堆q1
cout<< "定義一個(gè)大根堆q1: priority_queue,less>q1"<< endl;
q1.push(test(10));//向隊(duì)列中添加一個(gè)test,val的值為10
q1.push(test(5));//向隊(duì)列中添加一個(gè)test,val的值為5
q1.push(test(7));//向隊(duì)列中添加一個(gè)test,val的值為7
cout<< "按順序添加val的值為10、5、7的test,目前隊(duì)列的元素:test(10) test(5) test(7)"<< endl;
cout<< "q1.top().val="<< q1.top().val<< endl;
cout<< endl;
q1.pop();
cout<< "q1.pop()后,目前隊(duì)列的元素:test(5) test(7)"<< endl;
cout<< "q1.top().val="<< q1.top().val<< endl;
cout<< endl;
q1.pop();
cout<< "q1.pop()后,目前隊(duì)列的元素:test(5)"<< endl;
cout<< "q1.top().val="<< q1.top().val<< endl;
cout<< endl;
q1.pop();
cout<< "q1.pop()后,目前隊(duì)列是空的"<< endl;
cout<< "目前隊(duì)列是空的,不能使用q1.top()查詢(xún)隊(duì)首元素"<< endl;
cout<< endl<< endl;
priority_queue, greater>q2;//定義一個(gè)大頂堆q1
cout<< "定義一個(gè)小根堆q2: priority_queue,greate>q2"<< endl;
q2.push(test(10));//向隊(duì)列中添加一個(gè)test,val的值為10
q2.push(test(5));//向隊(duì)列中添加一個(gè)test,val的值為5
q2.push(test(7));//向隊(duì)列中添加一個(gè)test,val的值為7
cout<< "按順序添加val的值為10、5、7的test,目前隊(duì)列的元素:test(10) test(5) test(7)"<< endl;
cout<< "q2.top().val="<< q2.top().val<< endl;
cout<< endl;
q2.pop();
cout<< "q2.pop()后,目前隊(duì)列的元素:test(10) test(7)"<< endl;
cout<< "q2.top().val="<< q2.top().val<< endl;
cout<< endl;
q2.pop();
cout<< "q2.pop()后,目前隊(duì)列的元素:test(10)"<< endl;
cout<< "q2.top().val="<< q2.top().val<< endl;
cout<< endl;
q2.pop();
cout<< "q1.pop()后,目前隊(duì)列是空的"<< endl;
cout<< "目前隊(duì)列是空的,不能使用q2.top()查詢(xún)隊(duì)首元素"<< endl;
}
題目:dijkstra優(yōu)化
#include#include#include#includeusing namespace std;
const int N=150010,M=N*2,INF=0x3f3f3f3f;
typedef pairPII;
int head[N],e[N],ne[N],w[N];
int dist[N],st[N];
int idx,n,m;
void add(int a,int b,int c)
{e[idx]=b;
w[idx]=c;
ne[idx]=head[a];
head[a]=idx++;
}
int dijkstra()
{memset(dist,INF,sizeof dist);
dist[1]=0;
priority_queue,greater>heap;
heap.push({0,1});
while(heap.size())
{PII k=heap.top();
heap.pop();
int distance=k.first,ver=k.second;
if(st[ver]==1)continue;
else st[ver]=1;
for(int i=head[ver];i!=-1;i=ne[i])
{ int j=e[i];
if(st[j]==0&&dist[j]>distance+w[i])
{ dist[j]=distance+w[i];
heap.push({dist[j],j});
}
}
}
if(dist[n]==INF)return -1;
else return dist[n];
}
int main()
{cin>>n>>m;
memset(head,-1,sizeof head);
for(int i=0;iint a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
cout<
3.bellman_ford()算法核心:對(duì)所有的點(diǎn)進(jìn)行“對(duì)鄰接邊嘗試松弛”即dist[to]=min(dist[to],dist[from]+w[from][to]);
題目;bellmanford
#include#include#include
using namespace std;
const int N=100010;
struct edge
{int a,b,w;
}edge[N];
int dist[N];
int backup[N];
int n,m,k;
int bellman_ford()
{memset(dist,0x3f3f3f3f,sizeof dist);
dist[1]=0;
for(int i=1;i<=k;i++)
{memcpy(backup,dist,sizeof dist);
for(int j=1;j<=m;j++)
{ int a=edge[j].a,b=edge[j].b,w=edge[j].w;
dist[b]=min(dist[b],backup[a]+w);
}
}
return dist[n];
}
int main()
{cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{int a,b,c;
cin>>a>>b>>c;
edge[i].a=a,edge[i].b=b,edge[i].w=c;
}
int t=bellman_ford();
if(t>=0x3f3f3f3f/2)cout<<"impossible";
else cout<
4.spfa算法spfa算法就是bellman_ford算法的優(yōu)化版本
Bellman_ford算法會(huì)遍歷所有的邊,但是有很多的邊遍歷了其實(shí)沒(méi)有什么意義,我們只用遍歷那些到源點(diǎn)距離變小的點(diǎn)所連接的邊即可,只有當(dāng)一個(gè)點(diǎn)的前驅(qū)結(jié)點(diǎn)更新了,該節(jié)點(diǎn)才會(huì)得到更新;因此考慮到這一點(diǎn),我們將創(chuàng)建一個(gè)隊(duì)列每一次加入距離被更新的結(jié)點(diǎn)。
題目:spfa
#include#include#include
#includeusing namespace std;
const int N=1e5+10;
int head[N],e[N],ne[N],w[N],idx;
int dist[N],st[N];
int n,m;
void add(int a,int b,int c)
{e[idx]=b,ne[idx]=head[a],w[idx]=c,head[a]=idx++;
}
void spaf()
{queueq;
q.push(1);
dist[1]=0;
st[1]=1;
while(!q.empty())
{ int t=q.front();
q.pop();
st[t]=0;
for(int i=head[t];i!=-1;i=ne[i])
{ int a=e[i],b=w[i];
if(dist[a]>dist[t]+b)
{ dist[a]=dist[t]+b;
if(st[a]==0)
{st[a]=1;
q.push(a);
}
}
}
}
}
int main()
{cin>>n>>m;
memset(head,-1,sizeof head);
memset(dist,0x3f,sizeof dist);
for(int i=0;iint a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
spaf();
if(dist[n]==0x3f3f3f3f)
cout<<"impossible";
else
cout<
(2)含負(fù)環(huán)題目:spaf判斷負(fù)環(huán)
#include#include#include
#includeusing namespace std;
const int N=1e4+10;
int head[N],e[N],ne[N],w[N],idx;
int st[N],cnt[N],dist[N];
int n,m;
void add(int a,int b,int c)
{e[idx]=b,ne[idx]=head[a],w[idx]=c,head[a]=idx++;
}
bool spaf()
{queueq;
for(int i=1;i<=n;i++)
{q.push(i);
st[i]=1;
}
dist[1]=0;
while(!q.empty())
{int t=q.front();
q.pop();
st[t]=0;
for(int i=head[t];i!=-1;i=ne[i])
{ int j=e[i],k=w[i];
if(dist[j]>dist[t]+k)
{ dist[j]=dist[t]+k;
cnt[j]++;
if(cnt[j]>m)
return true;
if(st[j]==0)
{st[j]=1;
q.push(j);
}
}
}
}
return false;
}
int main()
{cin>>n>>m;
memset(head,-1,sizeof head);
memset(dist,0x3f,sizeof dist);
for(int i=0;iint a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
if(spaf())
cout<<"Yes";
else
cout<<"No";
return 0;
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧