您的位置:首页 > 其它

模板--最短路(简单)

2016-02-15 16:30 267 查看
POJ 1847为例。

/*
有N个路口,计算从a路口到b路口的最短转弯数。
对于每一个路口,有t个分叉口,第一个分叉口是直行,也就是不用转弯
剩下的t-1个路口都需要转弯一次。
*/

/************Dijkstra***************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;
 
int map[maxn][maxn], n, a, b, t, p;

int Dijkstra(int s, int e)//212K 47MS
{
int vis[maxn], dis[maxn];
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++)
dis[i] = map[s][i];
vis[s] = 1;
for (int i = 0; i < n; i++)
{
int k = -1;
int tmp = INF;
for (int j = 1; j <= n;j++)
if (!vis[j] && dis[j] < tmp)
{
k = j;
tmp = dis[j];
}
if (k == -1) break;
vis[k] = 1;
for (int j = 1; j <= n; j++)
if (!vis[j] && map[k][j] < INF)
dis[j] = min(dis[j], dis[k] + map[k][j]);
}
return dis[e];
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
while (~scanf("%d%d%d", &n, &a, &b))
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i == j) map[i][j] = 0;
else map[i][j] = INF;
for (int i = 1; i <= n; i++)
{
scanf("%d", &t);
for (int j = 1; j <= t; j++)
{
scanf("%d", &p);
if (j == 1) map[i][p] = 0;
else map[i][p] = 1;
}
}
int ans = Dijkstra(a, b);
if (ans == INF) ans = -1;
printf("%d\n", ans);
}
return 0;
}


/********Dijkstra+Heap*******/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;

struct Edge {
int v, w, next;
}edge[maxm];

int vis[maxn], head[maxn];
int n, a, b, t, p, tot;

void AddEdge(int from, int to, int dist, int k)
{
edge[k].v = to;
edge[k].w = dist;
edge[k].next = head[from];
head[from] = k;
}

struct HeapNode {
int dist, u;
bool operator < (const HeapNode& rhs) const {
return dist > rhs.dist;
}
}dis[maxn];

int Dijkstra_Heap(int s,int e)//184K 0MS
{
priority_queue<HeapNode> q;
while (!q.empty()) q.pop();
for (int i = 1; i <= n; i++)//结点标号:1--n
{
dis[i].u = i;
dis[i].dist = INF;
}
dis[s].dist = 0;
memset(vis, 0, sizeof(vis));
q.push(dis[s]);
while (!q.empty()) {
HeapNode x = q.top();
q.pop();
int u = x.u;
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].v;
int w = edge[i].w;
if (dis[v].dist > dis[u].dist + w) {
dis[v].dist = dis[u].dist + w;
q.push(dis[v]);
}
}
}
return dis[e].dist;
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
while (~scanf("%d%d%d", &n, &a, &b))
{
memset(head, -1, sizeof(head));
tot = -1;
for (int i = 1; i <= n; i++)
{
scanf("%d", &t);
for (int j = 1; j <= t; j++) {
tot++;
scanf("%d", &p);
if (j == 1) AddEdge(i, p, 0, tot);
else AddEdge(i, p, 1, tot);
}
}
int ans = Dijkstra_Heap(a, b);
if (ans == INF) ans = -1;
printf("%d\n", ans);
}
return 0;
}

/**********Floyd***********/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;
 
int map[maxn][maxn], n, a, b, t, p;

int floyd(int s,int e)//212K 16MS
{
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
return map[s][e];
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
while (~scanf("%d%d%d", &n, &a, &b))
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (i == j) map[i][j] = 0;
else map[i][j] = INF;
for (int i = 1; i <= n; i++)
{
scanf("%d", &t);
for (int j = 1; j <= t; j++)
{
scanf("%d", &p);
if (j == 1) map[i][p] = 0;
else map[i][p] = 1;
}
}
int ans=floyd(a,b);
if (ans == INF) ans = -1;
printf("%d\n", ans);
}
return 0;
}


/**************Bellman_Ford*********************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;
 
int n, a, b, uu, vv, ww, t, tot, p;
int dis[maxn];

struct Edge {
int u, v, w;
}edge[maxm];

int Bellman_Ford(int s, int e)//172K  0MS
{
for (int i = 1; i <= n; i++)
{
if (i == s) dis[i] = 0;
else dis[i] = INF;
}
for (int i = 0; i < n - 1; i++)
for (int j = 0; j <= tot; j++)
{
int x = edge[j].u;
int y = edge[j].v;
int z = edge[j].w;
dis[y] = min(dis[y], dis[x] + z);
}
return dis[e];
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
while (~scanf("%d%d%d", &n, &a, &b))
{
tot = -1;
for (int i = 1; i <= n; i++)
{
scanf("%d", &t);
for (int j = 1; j <= t; j++)
{
++tot;
scanf("%d", &p);
edge[tot].u = i;
edge[tot].v = p;
if (j == 1) edge[tot].w = 0;
else edge[tot].w = 1;
}
}
int ans = Bellman_Ford(a, b);
if (ans == INF) ans = -1;
printf("%d\n", ans);
}
return 0;
}


/***********SPFA+QUEUE***********/
/***********SPFA+STACK***********/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

const int maxn = 110;
const int maxm = 10010;
const int INF = 0x3f3f3f3f;

int dis[maxn], head[maxn], vis[maxn];
int n, a, b, t, p, tot;

struct Edge {
int v, w, next;
}edge[maxm];

void AddEdge(int u, int v, int w, int k)
{
edge[k].v = v;
edge[k].w = w;
edge[k].next = head[u];
head[u] = k;
}

int SPFA_QUEUE(int s, int e)//队列实现 184K 16MS
{
queue<int> q;
if (!q.empty()) q.pop();
for (int i = 1; i <= n; i++)
{
if (i == s) dis[i] = 0;
else dis[i] = INF;
}
memset(vis, 0, sizeof(vis));
vis[s] = 1;
q.push(s);
while (!q.empty())
{
int uu = q.front();
q.pop();
vis[uu] = 0;
for (int i = head[uu]; i != -1; i = edge[i].next)
{
int vv = edge[i].v;
int ww = edge[i].w;
if (dis[uu] < INF && dis[vv] > dis[uu] + ww)
{
dis[vv] = dis[uu] + ww;
if (!vis[vv])
{
vis[vv] = 1;
q.push(vv);
}
}
}
}
return dis[e];
}

int SPFA_STACK(int s, int e)//栈实现 184K 0MS
{
stack<int> q;
if (!q.empty()) q.pop();
for (int i = 1; i <= n; i++)
{
if (i == s) dis[i] = 0;
else dis[i] = INF;
}
memset(vis, 0, sizeof(vis));
vis[s] = 1;
q.push(s);
while (!q.empty())
{
int uu = q.top();
q.pop();
vis[uu] = 0;
for (int i = head[uu]; i != -1; i = edge[i].next)
{
int vv = edge[i].v;
int ww = edge[i].w;
if (dis[uu] < INF && dis[vv] > dis[uu] + ww)
{
dis[vv] = dis[uu] + ww;
if (!vis[vv])
{
vis[vv] = 1;
q.push(vv);
}
}
}
}
return dis[e];
}

int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
while (~scanf("%d%d%d", &n, &a, &b))
{
tot = -1;
memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++)
{
scanf("%d", &t);
for (int j = 1; j <= t; j++)
{
++tot;
scanf("%d", &p);
if (j == 1) AddEdge(i, p, 0, tot);
else AddEdge(i, p, 1, tot);
}
}
//int ans = SPFA_QUEUE(a, b);
int ans = SPFA_STACK(a, b);
if (ans == INF) ans = -1;
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最短路