SPFA
-
适用于稀疏图 队列优化的Bellman-Ford算法
-
时间复杂度 O(km)->O(mn)
-
稀疏图 正负边权 负环
-
实现:每次取队首顶点u,对顶点u的出边进行松弛操作,
将成功松弛的顶点v放置队尾. 所有出边松弛完毕之后,
将顶点u出队,循环取队首松弛直到队空 -
对于判断负环:如果某个点进入队列次数超过n次,
那么这个图肯定存在负环.
void SPFA(int k)
{
memset(vis, 0, sizeof vis);
memset(dis, 0x3f, sizeof dis);
dis[k] = 0;
queue<int>q;
q.push(k);
vis[k] = 1;
while(q.size())
{
int u = q.front();
vis[u] = 0;
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v= edge[i].v;
int w = edge[i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}
Dijstra
- 主要是看点的数量,复杂度为o(nlogn)
struct Node
{
int v, w;
Node(int vv, int ww):v(vv), w(ww){}
bool operator < (const Node& a) const
{
return w > a.w;
}
};
struct Edge
{
int v, w;
Edge(int vv, int ww):v(vv), w(ww){}
};
vector<Edge>edge[maxn];
void Dijstra(int n, int s)
{
memset(vis, 0, sizeof vis);
memset(dis, 0x3f, sizeof dis);
Node tmp(s, 0);
dis[s] = 0;
priority_queue<Node>q;
q.push(tmp);
while(q.size())
{
Node t = q.top();
q.pop();
int u = t.v;
if(vis[u])
continue;
vis[u] = 1;
for(int i = 0; i < (int)edge[u].size(); i++)
{
int v = edge[u][i].v;
int w = edge[u][i].w;
if(!vis[v] && dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push(Node(v, dis[v]));
}
}
}
}
HDU 2544 两种解法
- SPFA
//SPFA
//hdu 2544
const int maxn = 1e5+9;
int head[maxn], vis[maxn], dis[maxn];
int cnt;
int N, M;
struct Edge
{
int v, w, next;
}edge[maxn];
void addEdge(int u, int v, int w)
{
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void SPFA(int k)
{
memset(vis, 0, sizeof vis);
memset(dis, 0x3f, sizeof dis);
dis[k] = 0;
queue<int>q;
q.push(k);
vis[k] = 1;
while(q.size())
{
int u = q.front();
vis[u] = 0;
q.pop();
for(int i = head[u]; i != -1; i = edge[i].next)
{
int v= edge[i].v;
int w = edge[i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}
int main()
{
while(~scanf("%d%d", &N, &M) && N && M)
{
memset(head, -1, sizeof head);
cnt = 0;
for(int i = 0; i < M; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w);
addEdge(v, u, w);
}
SPFA(1);
printf("%d\n", dis[N]);
}
}
- Dijkstra
const int maxn = 110;
struct Node
{
int v, w;
Node(int vv, int ww):v(vv), w(ww){}
bool operator < (const Node& a) const
{
return w > a.w;
}
};
struct Edge
{
int v, w;
Edge(int vv, int ww):v(vv), w(ww){}
};
vector<Edge>edge[maxn];
int vis[maxn], dis[maxn];
int N, M;
void Dijstra(int n, int s)
{
memset(vis, 0, sizeof vis);
memset(dis, 0x3f, sizeof dis);
Node tmp(s, 0);
dis[s] = 0;
priority_queue<Node>q;
q.push(tmp);
while(q.size())
{
Node t = q.top();
q.pop();
int u = t.v;
if(vis[u])
continue;
vis[u] = 1;
for(int i = 0; i < (int)edge[u].size(); i++)
{
int v = edge[u][i].v;
int w = edge[u][i].w;
if(!vis[v] && dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
q.push(Node(v, dis[v]));
}
}
}
}
int main()
{
while(~scanf("%d%d", &N, &M) && N && M)
{
for(int i = 0; i < N; i++)
{
edge[i].clear();
}
int a, b, c;
for(int i = 0; i < M; i++)
{
scanf("%d%d%d", &a, &b, &c);
edge[a].push_back(Edge(b, c));
edge[b].push_back(Edge(a, c));
}
Dijstra(N, 1);
printf("%d\n", dis[N]);
}
return 0;
}
模板题
- HDU 1874
- POJ 2387 Til the Cows Come Home
- POJ 3259 Wormholes
- POJ 1860 Currency Exchange