被kuangbin带着飞-最短路
Posted littlerita
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了被kuangbin带着飞-最短路相关的知识,希望对你有一定的参考价值。
A - Til the Cows Come Home
板题;
#include<cstdio> #include<vector> #include<queue> using namespace std; #define pb push_back typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=1e3+5; int n,m; struct edge{int v,w;edge(int a,int b){v=a,w=b;}}; struct node{ int id,dis; node(int a,int b){id=a,dis=b;} friend bool operator<(node a,node b){ return a.dis>b.dis; } }; vector<edge>e[maxn]; int dis[maxn]; bool done[maxn]; void dijkstra(){ int s=1; for(int i=0;i<=n;i++)dis[i]=inf,done[i]=0; dis[s]=0; priority_queue<node>Q; Q.push(node(s,0)); while(!Q.empty()){ node u=Q.top();Q.pop(); if(done[u.id])continue; done[u.id]=1; for(int i=0;i<e[u.id].size();i++){ edge y=e[u.id][i]; if(done[y.v])continue; if(dis[y.v]>y.w+dis[u.id]){ dis[y.v]=y.w+u.dis; Q.push(node(y.v,dis[y.v])); } } } } int main(){ int t; scanf("%d %d",&t,&n); for(int i=1,u,v,w;i<=t;i++){ scanf("%d %d %d",&u,&v,&w); e[u].pb(edge(v,w)); e[v].pb(edge(u,w)); } dijkstra(); printf("%d ",dis[n]); // system("pause"); return 0; }
题意:就是说给你一个图里很多点的坐标,问你从一个点跳到另一个点有许多路径,
求最小的经过的路径最大的一步,就是最大值最小化;
考虑floyd类似动态规划,
gp[i][j]=min(gp[i][j],max(gp[i][k],gp[k][j]));
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++) #define per(i,j,k) for(int i=(int)k;i>=(int)j;i--) #define pb push_back typedef double db; const int maxn=2e2+5; struct point{db x,y;}P[maxn]; db dis(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));} db gp[maxn][maxn]; int main(){ int n,cas=0; while(~scanf("%d",&n),n){ for(int i=1;i<=n;i++)scanf("%lf %lf",&P[i].x,&P[i].y); // db ans=dis(P[1],P[2]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) gp[i][j]=dis(P[i],P[j]); for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) gp[i][j]=min(gp[i][j],max(gp[i][k],gp[k][j])); db ans=gp[1][2]; printf("Scenario #%d ",++cas); printf("Frog Distance = %.3lf ",ans); } // system("pause"); return 0; }
C - Heavy Transportation
题意:点1到点n,多条路径每条路径都有最小边,求最大的最小边;
这是个最小值最大化问题;
考虑最大生成树做法;
就是边从大到小排序,每次合并,如果1到n联通成功,那么值就是当前边权;
为什么?
#include<cstdio> #include<vector> #include<queue> #include<algorithm> using namespace std; #define pb push_back typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=1e3+5; int n,m; int fa[maxn]; struct edge{int u,v,w;edge(int a,int b,int x){u=a,v=b,w=x;}}; vector<edge>e; bool cmp(edge a,edge b){return a.w>b.w;} void init(){for(int i=1;i<=maxn;i++)fa[i]=i;} int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} void build(int x,int y){int dx=find(x),dy=find(y);if(dx!=dy)fa[dx]=dy;} int main(){ int t,cas=0; scanf("%d",&t); while(t--){ e.clear(); scanf("%d %d",&n,&m); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1,u,v,w;i<=m;i++){ scanf("%d %d %d",&u,&v,&w); e.pb(edge(u,v,w)); } sort(e.begin(),e.end(),cmp); int ans=0; for(int i=0;i<e.size();i++){ build(e[i].v,e[i].u); if(find(1)==find(n)){ans=e[i].w;break;} } printf("Scenario #%d: ",++cas); printf("%d ",ans); } // system("pause"); return 0; }
以上是关于被kuangbin带着飞-最短路的主要内容,如果未能解决你的问题,请参考以下文章