题目地址:hdu2544
就是直接求最短路 数据很弱 什么方法都可以
1 floyd
#include<iostream>
using namespace std;
#define INF 10000009
int d[105][105];
int n,m;
void init()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
d[i][j]=(i==j?0:INF);
}
// 1 floyd 2 Dijkstra 3 Bellman-Ford 4 Dijkstra priority_queue 5 Bellman-Ford with queue
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int u,v,w;
for(int i=0;i<m;i++)
{
cin>>u>>v>>w;
d[u-1][v-1]=w;
d[v-1][u-1]=w;
}
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(d[i][k]!=INF&&d[k][j]!=INF)d[i][j]=d[i][j]<(d[i][k]+d[k][j])?d[i][j]:(d[i][k]+d[k][j]);
cout<<d[0][n-1]<<endl;
}
}
2 Dijkstra 赤裸裸的小白书代码
#include<iostream>
using namespace std;
#define INF 10000009
int d[105];
int n,m;
//struct
//{
// int u;
// int v;
// int w;
//
//} e[10005];
int done[10005];
int w[105][105];
void init()
{
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
memset(done, 0, sizeof(done));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
w[i][j]=(i==j?0:INF);
}
// 1 floyd 2 Dijkstra 3 Bellman-Ford 4 Dijkstra priority_queue 5 Bellman-Ford with queue
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int a,b,c;
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
// e[i].u=a-1;
// e[i].v=b-1;
// e[i].w=c;
w[a-1][b-1]=c;
w[b-1][a-1]=c;
}
// Dijkstra
for(int i=0;i<n;i++)
{
int x;
int m=INF;
for(int y=0;y<n;y++)
if(done[y]==0&&d[y]<=m) m=d[x=y];
done[x]=1;
for(int y=0;y<n;y++)
if(w[x][y]!=INF) d[y]=min(d[y],d[x]+w[x][y]);
}
cout<<d[n-1]<<endl;
}
}
3 Dijkstra 使用优先队列优化
记住要将无向图转化为有向图
#include<iostream>
#include<utility>
#include<vector>
#include<queue>
using namespace std;
#define INF 1000000009
typedef pair<int, int> pii;
int d[1005];
int nxt[200010];
int first[1005];
int n,m;
struct
{
int u;
int v;
int w;
} e[200010];
int done[1005];
//int w[105][105];
void init()
{
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
memset(done, 0, sizeof(done));
memset(first,-1,sizeof(first));
// for(int i=0;i<n;i++)
// for(int j=0;j<n;j++)
// w[i][j]=(i==j?0:INF);
}
// 1 floyd 2 Dijkstra 3 Bellman-Ford 4 Dijkstra priority_queue 5 Bellman-Ford with queue
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int a,b,c;
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
e[i].u=a-1;
e[i].v=b-1;
e[i].w=c;
nxt[i]=first[a-1];
first[a-1]=i;
// w[a-1][b-1]=c;
// w[b-1][a-1]=c;
}
for(int i=0;i<m;i++)
{
e[i+m].u=e[i].v;
e[i+m].v=e[i].u;
e[i+m].w=e[i].w;
nxt[i+m]=first[e[i].v];
first[e[i].v]=i+m;
}
// Dijkstra with priority_queue;
priority_queue<pii,vector<pii>,greater<pii> > pq;
pq.push(make_pair(d[0], 0));
while(!pq.empty())
{
pii u=pq.top();
pq.pop();
int x=u.second;
if(done[x]) continue;
done[x]=1;
for(int i=first[x];i!=-1;i=nxt[i])
{
int y=e[i].v;
if(d[y]>d[x]+e[i].w)
{
d[y]=d[x]+e[i].w;
pq.push(make_pair(d[y],y));
}
}
}
cout<<d[n-1]<<endl;
}
}
4 Bellman-Ford
#include<iostream>
#include<utility>
#include<vector>
#include<queue>
using namespace std;
#define INF 1000000009
typedef pair<int, int> pii;
int d[1005];
int n,m;
struct
{
int u;
int v;
int w;
} e[200010];
void init()
{
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
}
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int a,b,c;
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
e[i].u=a-1;
e[i].v=b-1;
e[i].w=c;
}
for(int i=0;i<m;i++)
{
e[i+m].u=e[i].v;
e[i+m].v=e[i].u;
e[i+m].w=e[i].w;
}
//Bellman-Ford
for(int k=0;k<n-1;k++)
{
for(int i=0;i<2*m;i++)
{
int x=e[i].u;
int y=e[i].v;
if(d[x]<INF) d[y]=min(d[y],d[x]+e[i].w);
}
}
cout<<d[n-1]<<endl;
}
}
5 使用队列优化的Bellman-Ford (SPFA)
#include<iostream>
#include<utility>
#include<vector>
#include<queue>
using namespace std;
#define INF 1000000009
int d[105];
int first[105];
int nxt[20005];
int inq[105];
int n,m;
struct
{
int u;
int v;
int w;
} e[20005];
void init()
{
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
memset(first, -1, sizeof(first));
}
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int a,b,c;
for(int i=0;i<m;i++)
{
cin>>a>>b>>c;
e[i].u=a-1;
e[i].v=b-1;
e[i].w=c;
nxt[i]=first[a-1];
first[a-1]=i;
}
for(int i=0;i<m;i++)
{
e[i+m].u=e[i].v;
e[i+m].v=e[i].u;
e[i+m].w=e[i].w;
nxt[i+m]=first[e[i].v];
first[e[i].v]=i+m;
}
//Bellman-Ford with_queue SPFA
queue<int> q;
q.push(0);
while(!q.empty())
{
int x=q.front();
q.pop();
inq[x]=0;
for(int i=first[x];i!=-1;i=nxt[i])
{
int y=e[i].v;
if(d[y]>d[x]+e[i].w)
{
d[y]=d[x]+e[i].w;
if(!inq[y])
{
inq[y]=1;
q.push(y);
}
}
}
}
cout<<d[n-1]<<endl;
}
}
需要注意的是 因为SPFA能处理负权值 ,所以 关键是 踢出队列以后 把在inq这个标记清除了
和在Dijkstra 中, 踢出队列仍然不用做任何操作
只需要维护done数组 ,已经做过就不要再进队 出队了(出队就是“进入A集合”) 然后更新后重新进入优先队列 因为只要进入 优先级一定比更新之前的那个pair高 那么一定会先完成done[x]=1 操作 ,没有扔掉的也无所谓了。
额
如果不喜欢向前星 用vector邻接表也行
这里还是全部重新用vector 打一遍
1用pq 维护的DIjkstra 使用vector版本
(注: 需要说明的是 ,这里的队列和SPFA里的队列完全不同 ,这里仅仅是取出当前d值最小的快速方法而SPFA里面的队列是是为了BFS)
代码:
#include<iostream>
#include<vector>
#include<utility>
#include<queue>
using namespace std;
typedef pair<int,int> pii;
#define INF 1000000009
int d[105];
int done[105];
vector<int> G[1000];
vector<int> E[1000];
int n,m;
int min(int a,int b)
{
return a<b?a:b;
}
void init()
{
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
for(int i=0;i<n;i++) // 取代前向星
{
G[i].clear();
E[i].clear();
}
memset(done, 0, sizeof(done));
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int u,v,w;
for(int i=0;i<m;i++)
{
cin>>u>>v>>w;
G[u-1].push_back(v-1);
G[v-1].push_back(u-1);
E[u-1].push_back(w);
E[v-1].push_back(w);
}
// Dijkstra with priority_queue
priority_queue<pii,vector<pii>,greater<pii> >pq;
pq.push(make_pair(d[0], 0));
while(!pq.empty())
{
pii u=pq.top();
pq.pop();
int x=u.second;
if(done[x]) continue;
done[x]=1;
int s=G[x].size();
for(int i=0;i<s;i++)
{
int y=G[x][i];
if(d[x]+E[x][i]<d[y])
{
d[y]=d[x]+E[x][i];
pq.push(make_pair(d[y],y));
}
}
}
cout<<d[n-1]<<endl;
}
}
2 SPFA vector版本
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define INF 1000000009
int n,m;
int d[105];
int inq[105];
vector<int> G[105];
vector<int> E[105];
void init()
{
for(int i=0;i<n;i++)
d[i]=(i==0?0:INF);
memset(inq, 0, sizeof(inq));
for(int i=0;i<n;i++)
{
G[i].clear();
E[i].clear();
}
}
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
while(cin>>n>>m)
{
if(n==0&&m==0) break;
init();
int u,v,w;
for(int i=0;i<m;i++)
{
cin>>u>>v>>w;
G[u-1].push_back(v-1);
G[v-1].push_back(u-1);
E[u-1].push_back(w);
E[v-1].push_back(w);
}
//
// for(int i=0;i<m;i++)
// {
// e[i+m].u=e[i].v;
// e[i+m].v=e[i].u;
// e[i+m].w=e[i].w;
// }
// SPFA
queue<int> q;
q.push(0);
while(!q.empty())
{
int x=q.front();
q.pop();
inq[x]=0;
int s=G[x].size();
for(int i=0;i<s;i++)
{
int y=G[x][i];
if(d[y]>d[x]+E[x][i])
{
d[y]=d[x]+E[x][i];
if(!inq[y])
{
inq[y]=1;
q.push(y);
}
}
}
}
cout<<d[n-1]<<endl;
}
}