您的位置:首页 > 其它

|算法讨论|最短路 学习笔记

2017-03-11 16:54 393 查看
模板及讲解

常见题型:

1. 常规最短路

Q:求两点最短路。

解:堆优化dijkstra

例题:Tyvj 1031(非堆优化版本)

2. 次短路

Q:求两点次短路。

解:

例题:

3. 最小环

Q:求两点最小环。

解:Floyd求最短路时顺便求出。

例题:vijos 1046

4. 特殊的最短路

Q:求两点最短路,其中可以免费走过k条边。

解:分层图最短路。

例题:BZOJ 2763

//堆优化dijkstra
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ms(i,j) memset(i,j, sizeof i);
using namespace std;
struct node//dijkstra结点
{
int d;
int u;
bool operator<(const node &a) const//重载小于号,用于priority的比较
{
return d>a.d;
}
};
priority_queue<node> q; //堆
int dis[2505];
int vi[2505];
int t,c,ts,te;
int G[2505][2505];//邻接矩阵储存
int dij()
{
q.push((node){dis[ts], ts});//入堆
while (!q.empty())
{
node p = q.top(); q.pop();
if(vi[p.u]) continue;//已经标记过
vi[p.u] = true;
for (int i=1;i<=t;i++)//松弛
if(dis[p.u]+G[p.u][i]<dis[i])
{
dis[i] = dis[p.u]+G[p.u][i];
q.push((node){dis[i], i});
}
}
}
int main()
{
scanf("%d%d%d%d", &t,&c,&ts,&te);
ms(G,127);//初始化矩阵
ms(vi,false);
ms(dis,127); dis[ts] = 0;
for (int i=1;i<=c;i++)
{
int rs,re,ci;
scanf("%d%d%d", &rs, &re, &ci);
G[rs][re] = G[re][rs] = ci;
}
dij();
printf("%d\n", dis[te]);
return 0;
}


//求最小环
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ms(i,j) memset(i, j, sizeof(i));
using namespace std;
int n,m;
int G[102][102];
int dis[102][102];
int main ()
{
while(scanf("%d%d", &n, &m)==2)
{
ms(G,27);
for (int i=1;i<=m;i++)
{
int a,b,c;
scanf("%d%d%d", &a,&b,&c);
G[a][b]=G[b][a]=c;
}
memcpy(dis,G,sizeof(G));
int ans = 10000000;
for (int k=1;k<=n;k++)
{
for (int i=1;i<=k-1;i++)
for (int j=1;j<=k-1;j++)
ans = min(ans, dis[i][j]+G[j][k]+G[k][i]);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (k!=i&&k!=j&&i!=j)
dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
}
if (ans==10000000) printf("No solution.\n");
else printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: