题意概括:有n路口,m条路,每条路都有其能承载的最大值,意思就是说如果超过这个最大值就算超重就不能在这条路上走,需要找出一条路径,这条路径在所有路径中拥有最大的承载量。一条路径的最大承载量是这条路径里面所有路的最小承载量,因为肯定要经过这个最小承载量所在的路,如果大于他就是超重了。如样例,可以找出两条路径 1—2—3 里面的承载量分别是3,5,而这条路径的最大承载量就是3,大于3,1到2就无法行走;另一条是1—3承载量是4,所以最后找出的最大承载量是4。
解题思路:开始是按照Dijkstra写的,但是后来发现用Kruskal更简单。
代码1:Dijkstra
#include<stdio.h> #include<string.h> #define N 1100 #define INF 0x3f3f3f int map[N][N]; int d[N]; int visit[N]; int n; int min(int a,int b) { if(a>b) a=b; return a; } void Dijkstra(int x) { memset(visit,0,sizeof(visit)); int i,j; for(i=1;i<=n;i++) { d[i]=map[x][i]; } for(i=1;i<=n;i++) { int min_cost = -1; int index; for(j=1;j<=n;j++) { if(visit[j]==0&&d[j]>min_cost) { min_cost=d[j]; // printf("%d\n",d[j]); index=j; } } visit[index]=1; // printf("%d\n\n\n",index); for(j=1;j<=n;j++) { if(visit[j]==0&&d[j]<min(map[index][j],min_cost)) { d[j]=min(map[index][j],min_cost); } } } printf("%d\n\n",d[n]); } int main() { int i,j,m,k,l,u,v,w; int T,t=0; scanf("%d",&T); while(T--) { t++; scanf("%d%d",&n,&m); memset(map,0,sizeof(map)); for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); map[u][v]=map[v][u]=w; } printf("Scenario #%d:\n",t); Dijkstra(1); } return 0; }代码2:Kruskal#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define M 1100000 #define N 110000 struct edge { int u,v,w; }e[M]; int i,j,m,n; int f[N]; int min(int a,int b) { if(a>b) a=b; return a; } bool cmp(edge a,edge b) { return a.w>b.w; } int getf(int u) { if(f[u]==u) { return u; } else { f[u]=getf(f[u]); return f[u]; } } int merge (int u,int v) { int t1=getf(u); int t2=getf(v); if(t1!=t2) { f[t2]=t1; return 1; } return 0; } void Kruskal() { int num=0,sum=99999999; for(i=1;i<=n;i++) { f[i]=i; } for(i=0;i<m;i++) { if(merge(e[i].u,e[i].v)) { sum=min(sum,e[i].w); if(getf(1)==getf(n)) { break; } } } printf("%d\n\n",sum); } int main() { int t=0,T; scanf("%d",&T); while(T--) { t++; scanf("%d%d",&n,&m); for(i=0;i<m;i++) { scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w); } sort(e,e+m,cmp); printf("Scenario #%d:\n",t); Kruskal(); } return 0; }