Description
从城市1到城市n运送货物,有m条道路,每条道路都有它的最大载重量,问从城市1到城市n运送最多的重量是多少
Input
第一行一个整数T表示用例组数,每组用例第一行两个整数n和m表示城市数量和道路数量,之后m行每行三个整数a,b,c表示城市a到城市b的道路最大载重量为c(路是双向的)
Output
对于每组用例,输出从城市1到城市n最多能运送多重的货物
Sample Input
1
3 3
1 2 3
1 3 4
2 3 5
Sample Output
Scenario #1:
4
Solution
此题其实就是找到一条从1到n的路径使得路径上最小权值最大化,模仿prim算法求最小生成树的过程,每次只要将不属于生成树的边集中权值最大的边加到生成树中并更新最小值即可,而我的做法是将权值取相反数,那么就成了求最小生成树中的边权最大值,最后的结果再取相反数即为答案
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 1111
#define INF 0x3fffffff
int cost[maxn][maxn];
int mincost[maxn];
bool used[maxn];
int V;
int prim()
{
for(int i=0;i<V;i++)
{
mincost[i]=cost[0][i];
used[i]=false;
}
used[0]=true;
int ans=-INF;
for(int i=1;i<V;i++)
{
int v=-1;
int minc=INF;
for(int u=0;u<V;u++)
if(!used[u]&&mincost[u]<minc)
v=u,minc=mincost[u];
if(v==-1)break;
used[v]=true;
ans=max(ans,minc);
if(v==V-1)break;
for(int u=0;u<V;u++)
mincost[u]=min(mincost[u],cost[u][v]);
}
return ans;
}
int main()
{
int t,n,m,u,v,c,res=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
V=n;
for(int i=0;i<V;i++)
for(int j=0;j<V;j++)
cost[i][j]=INF;
while(m--)
{
scanf("%d%d%d",&u,&v,&c);
u--,v--,c=-c;
cost[u][v]=cost[v][u]=c;
}
int ans=-1*prim();
printf("Scenario #%d:\n",res++);
printf("%d\n\n",ans);
}
}