admin管理员组文章数量:1794759
过路费
问题描述:
有一天你来到了一个奇怪的国家,它有 N 个城市,城市之间有若干条双向道路连接,每条道路都有一定的费用,经过城市也要一定的费用。从一个城市到达另一个城市的总花费为路径上费用最大的城市费用(包括起点和终点)加上路径上所有的道路的费用。给出 Q 次询问,分别回答每次询问中两城市间的最少花费。保证城市之间可以互达。
这道题主要是需要了解Floyd的更新方法。
对于Floyd,由于我们第一层循环枚举中转点k,对于 i ,j 的更新,我们会看 i ---> k ,k ---> j,换句话说,我们在考虑 i 到 j 的路径的时候,只会经过{1,2,3,...,k}U{i,j}中的点。
所以先把点权从小到大排序,那么此时路径上最大的点权就是 i ,j , k 中的一个了。
这样的话,我们就可以直接得到现在路径中点权的最大值,剩下的就是 floyd 了。
代码(BZOJ删了这道题,写完没处交,反正很短,直接复制):
#include<stdio.h> #include<algorithm> #define MAXN 305 using namespace std;int N,M,Q,Map[MAXN][MAXN],Ans[MAXN][MAXN],Hash[MAXN];struct node {int c,id; } V[MAXN]; bool operator<(node x,node y) {return x.c<y.c; }int main() {int i,j,k,x,y,z;scanf("%d%d",&N,&M);for(i=1; i<=N; i++)scanf("%d",&V[i].c),V[i].id=i;sort(V+1,V+N+1);for(i=1; i<=N; i++)Hash[V[i].id]=i;for(i=1; i<=N; i++)for(j=1; j<=N; j++)Map[i][j]=Ans[i][j]=1e9;for(i=1; i<=N; i++)Map[i][i]=0;for(i=1; i<=M; i++){scanf("%d%d%d",&x,&y,&z);x=Hash[x];y=Hash[y];Map[x][y]=min(Map[x][y],z);Map[y][x]=Map[x][y];}for(k=1; k<=N; k++)for(i=1; i<=N; i++)for(j=1; j<=N; j++){Map[i][j]=min(Map[i][k]+Map[k][j],Map[i][j]);Ans[i][j]=min(Ans[i][j],Map[i][j]+max(V[i].c,max(V[j].c,V[k].c)));}scanf("%d",&Q);for(i=1; i<=Q; i++){scanf("%d%d",&x,&y);x=Hash[x];y=Hash[y];printf("%d\n",Ans[x][y]);}return 0; }
{1,2,3,…,k}⋃{i,j} {1,2,3,…,k}⋃{i,j}
中的点!
转载于:.html
本文标签: 过路费
版权声明:本文标题:过路费 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1700942150a414256.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论