POJ 1797 Heavy Transportation
dijkstra
\(dijkstra\)求最短路中我们每次选取的是离原点的最短边来松弛剩下的节点
在这里我们要找到到达终点的的一条路使其路径上的最小边尽量大,才能使其载重量较大。
也就是说每次选择一个从源点到某个载重量最大的点,来松弛其他点。
\(dist\)将记录到达每个点的路径上的最小载重,选择最大的最小载重能让整条路径的最小载重变大。
利用这个路径上最大的最小载重去更新其他点使到达其他点的最小载重变大,最终使到达每个点最小载重都最大。
const int N=1010;
vector<PII> g[N];
int dist[N];
bool vis[N];
int n,m;
void dijkstra()
{
memset(dist,0,sizeof dist);
memset(vis,0,sizeof vis);
priority_queue<PII> heap;
dist[1]=INF;
heap.push({dist[1],1});
while(heap.size())
{
int t=heap.top().se;
heap.pop();
if(vis[t]) continue;
vis[t]=true;
for(int i=0;i<g[t].size();i++)
{
int j=g[t][i].fi,w=g[t][i].se;
if(dist[j] < min(dist[t],w))
{
dist[j]=min(dist[t],w);
heap.push({dist[j],j});
}
}
}
}
int main()
{
ios;
int T;
cin>>T;
int kase=1;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++) g[i].clear();
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
g[a].pb({b,c});
g[b].pb({a,c});
}
dijkstra();
cout<<"Scenario #"<<kase++<<":"<<endl;
cout<<dist[n]<<endl<<endl;
}
//system("pause");
}
kruskal
求最大生成树,当\(1\)号点和\(n\)号点第一次连通时的边即为所求
const int N=1010,M=N*N;
struct Node
{
int a,b,c;
bool operator<(const Node &W) const
{
return c>W.c;
}
}e[M];
int p[N];
int n,m;
int find(int x)
{
if(x != p[x]) p[x]=find(p[x]);
return p[x];
}
int kruskal()
{
for(int i=1;i<=n;i++) p[i]=i;
int res=0;
for(int i=0;i<m;i++)
{
if(find(1) == find(n)) return res;
int a=e[i].a,b=e[i].b,c=e[i].c;
int pa=find(a),pb=find(b);
if(pa != pb)
{
p[pa]=pb;
res=c;
}
}
}
int main()
{
ios;
int T;
cin>>T;
int kase=1;
while(T--)
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
e[i]={a,b,c};
}
sort(e,e+m);
int t=kruskal();
cout<<"Scenario #"<<kase++<<":"<<endl;
cout<<t<<endl<<endl;
}
//system("pause");
}