poj2253Frogger(最短路变形)及poj1797Heavy Transportation(最大生成树)

来源:互联网 发布:奇迹暖暖每章套装知乎 编辑:程序博客网 时间:2024/06/04 20:03

题目大意,有两只青蛙,分别在两个石头上,青蛙A想要到青蛙B那儿去,他可以直接跳到B的石头上,也可以跳到其他石头上,再从其他石头跳到B那儿,求青蛙从A到B的所有路径中最小的Frog Distance,定义Frog Distance为从A到B的一条路径中所跳的最大距离,例如,如果从A到B某条路径跳的距离是9,1,6,5,则Frog Distance就是9,注意每输出一个答案还要再空一行。
其实这道题就是求最小生成树的最大权,也就是说用最小生成树是可以做的,但是这道题只需将最短路中源点到终点的距离dis[i]换成源点到终点路径上边的最大距离,dis[i]=max(dis[i],dis[p]+cos[p][i})换成dis[i}换成min(dis[i},max(dis[p},cos[p}[i})就可以了。

32ms。

#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <queue>#include <math.h>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))#define mpow(X) ((X)*(X))typedef long long LL;using namespace std;const int MAXN=205;const double INF=1e10;struct _Point{    int x,y;}point[MAXN];double d[MAXN],cost[MAXN][MAXN];bool vs[MAXN];inline double dis(int u,int v){return sqrt((double)(mpow(point[u].x-point[v].x)+mpow(point[u].y-point[v].y))); }void Dijst(int n,int beg){    ms(vs);    for(int i=0;i<n;i++) d[i]=cost[0][i];    for(int i=0;i<n;i++)    {        double minc=INF;        int p=-1;        for(int j=0;j<n;j++)            if(!vs[j]&&d[j]<minc)                minc=d[p=j];        vs[p]=true;        if(p==1) break;//答案已经出来了        for(int j=0;j<n;j++)            if(!vs[j]){            double maxx=max(d[p],cost[p][j]);            if(maxx<d[j]) d[j]=maxx;            }    }}int main(int argc, char const *argv[]){    int ti=0,n;    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=0;i<n;i++)            scanf("%d %d",&point[i].x,&point[i].y);        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)                if(i==j) cost[i][j]=0.0;                else cost[i][j]=cost[j][i]=dis(i,j);        Dijst(n,0);    printf("Scenario #%d\nFrog Distance = %.3f\n\n",++ti,d[1] );    }    return 0;}

用Prim算法的做法,速度要再快一点,0ms。

#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <queue>#include <math.h>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))#define mpow(X) ((X)*(X))typedef long long LL;using namespace std;const int MAXN=205;const double INF=1e10;struct _Point{    int x,y;}point[MAXN];double lowc[MAXN],cost[MAXN][MAXN];bool vs[MAXN];inline double dis(int u,int v){return sqrt((double)(mpow(point[u].x-point[v].x)+mpow(point[u].y-point[v].y))); }double ans;void Prim(int n,int beg){    ms(vs);    for(int i=0;i<n;i++) lowc[i]=cost[0][i];    for(int i=0;i<n;i++)    {        double minc=INF;        int p=-1;        for(int j=0;j<n;j++)            if(!vs[j]&&lowc[j]<minc)                minc=lowc[p=j];        vs[p]=true;        ans=max(minc,ans);        if(p==1) break;        for(int j=0;j<n;j++)            if(!vs[j]&&lowc[j]>cost[p][j])                lowc[j]=cost[p][j];    }}int main(int argc, char const *argv[]){    int ti=0,n;    while(scanf("%d",&n)!=EOF&&n)    {        for(int i=0;i<n;i++)            scanf("%d %d",&point[i].x,&point[i].y);        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)                if(i==j) cost[i][j]=0.0;                else cost[i][j]=cost[j][i]=dis(i,j);        ans=0.0;        Prim(n,0);    printf("Scenario #%d\nFrog Distance = %.3f\n\n",++ti,ans );    }    return 0;}

与这道题相反一道题poj1797
最大生成树的最小权,当然同样这道题可以用dijkstra算法,只需将最短路中源点到终点的距离dis[i]换成源点到终点路径上边最小距离,dis[i]=max(dis[i],dis[p]+cos[p][i})换成dis[i}换成max(dis[i},min(dis[p},cos[p}[i})就可以了。(dis从大到小贪心)
以下是用Prim算法做的。

#include <iostream>#include <stdio.h>#include <algorithm>#include <stdlib.h>#include <stack>#include <vector>#include <string.h>#include <queue>#define msc(X) memset(X,-1,sizeof(X))#define ms(X) memset(X,0,sizeof(X))typedef long long LL;using namespace std;const int MAXN=1010;const int INF=0x3f3f3f3f;int cost[MAXN][MAXN],ans,upc[MAXN];bool vs[MAXN];//最大生成树void Prim(int n,int beg){    ms(vs);    for(int i=1;i<n;i++) upc[i]=cost[0][i];    vs[0]=true;    for(int i=1;i<n;i++)    {        int maxc=0,p=-1;        for(int j=1;j<n;j++)            if(!vs[j]&&maxc<upc[j])                maxc=upc[p=j];        vs[p]=true;        ans=min(maxc,ans);        if(p==n-1) break;        for(int j=1;j<n;j++)            if(!vs[j]&&upc[j]<cost[p][j])                upc[j]=cost[p][j];    }}int main(int argc, char const *argv[]){    int ti=0,t;    cin>>t;    while(++ti<=t)    {        int n,m;        scanf("%d %d",&n,&m);        ms(cost);        while(m--)        {            int a,b,w;            scanf("%d %d %d",&a,&b,&w);            a--,b--;            cost[a][b]=cost[b][a]=max(cost[a][b],w);        }        ans=INF;        Prim(n,0);        printf("Scenario #%d:\n%d\n\n",ti,ans);    }    return 0;}
0 0
原创粉丝点击