当然这题用dijkstra和floyd都行,仅仅只是改变松弛条件,另外更简单的方法可以用kruskal,因为边按权值排序,当起点和终点正好加到生成树中时,得到的路径就是答案.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 0X7FFFFFFF
using namespace std;
int C,S,Q;
struct Edge
{
int u,v,w;
};
struct Node
{
int w,u;
Node(int _w,int _u):w(_w),u(_u){}
bool operator <(const Node &other) const
{
return w>other.w;
}
};
Edge edges[1005];
vector<int> G[105];
priority_queue<Node> PQ;
bool vis[105];
int d[105];
void dijsktra(int s,int t)
{
while (!PQ.empty())
PQ.pop();
memset(vis, false, sizeof(vis));
for (int i=1; i<=C; i++)
d[i]=INF;
d[s]=0;
PQ.push(Node(0,s));
while (!PQ.empty())
{
Node node=PQ.top();
PQ.pop();
int u=node.u;
if (vis[u])
continue;
if (u==t)
{
printf("%d\n",node.w);
return;
}
vis[u]=true;
//松弛操作
for (int i=0; i<G[u].size();i++)
{
//获取与u邻接的边
Edge &e=edges[G[u][i]];
//确定始点和终点
int from=u==e.u?u:e.v;
int to=u==e.u?e.v:e.u;
if (d[to]>max(d[from], e.w))//松弛条件
{
d[to]=max(d[from], e.w);
PQ.push(Node(d[to], to));
}
}
}
printf("no path\n");
}
int main()
{
int _case=0;
bool p=false;
while (scanf("%d %d %d",&C,&S,&Q)!=EOF&&C!=0&&S!=0&&Q!=0)
{
if (p)
{
printf("\n");
}
printf("Case #%d\n",++_case);
for (int i=0; i<105; i++)
G[i].clear();
for (int i=0; i<S; i++)
{
scanf("%d %d %d",&edges[i].u,&edges[i].v,&edges[i].w);
//添加以u邻接的边序号
G[edges[i].u].push_back(i);
G[edges[i].v].push_back(i);
}
//dijkstra nlogn
while (Q-->0)
{
int s,t;
scanf("%d %d",&s,&t);
dijsktra(s,t);
}
p=true;
//printf("\n");
}
}