数据结构总结之最短路径

来源:互联网 发布:淘宝绑定支付宝 编辑:程序博客网 时间:2024/06/04 19:45

1.弗洛伊德算法模板题:uva10000

#include<iostream>#include <string.h>using namespace std;int dis[105][105];int main(){    int n;int t =0;    while(cin>>n,n)    {        int a,b,s;        memset(dis,-1,sizeof(dis));        cin>>s;        while(cin>>a>>b,a)            dis[a][b] = 1;        int i,j;        for(int k=1;k<=n;k++)        for(i=1;i<=n;i++)            for(j=1;j<=n;j++)                if(dis[i][j]!=-1 && dis[j][k]!=-1)                            dis[i][k] = max(dis[i][k],dis[i][j]+dis[j][k]);        int max_ = -1;        int ans_node = 0 ;        for(i=1;i<=n;i++)        {            if(max_<dis[s][i])            {                max_ = dis[s][i];                ans_node  = i;            }        }        cout<<"Case "<<++t<<": The longest path from "<<s<<" has length "        <<max_<<", finishing at "<<ans_node<<"."<<endl<<endl;    }    return 0;}

2.路径长度和最小:

//par[i][j]:i和j间距,不相连就是MAXvoid Dij(){    memset(vis,0,sizeof(vis));    for( int i=2; i<=n; i++ )    dis[i] = par[1][i];    dis[1] = 0;    vis[1] = 1;    for( int i=0; i<n; i++ )    {        int temp= INF;         int v = -1; // 定义一个-1 ,方便判断是不是有边的存在(或边是否已全部加入 已连接点 的集合)        for( int j=1; j<=n; j++ ) // 由于每一个点都要进行一遍边的判定,所以是两个for         {            if( temp > dis[j] && !vis[j] )            {                temp = dis[j];                v = j;            }        }         if( v == -1 )  return; //如果全部边加完了(或者没有边),直接退出        vis[v] = 1;        for( int j=1; j<=n; j++ )// 更新         {            if( !vis[j] && dis[j] > dis[v]+par[v][j] )                dis[j] = dis[v]+par[v][j];        }     }   }

3.路径的最大值最小(也就是“边长”有限制):uva534

#include <iostream>#include <string.h>#include <algorithm>#include <math.h>#include <iomanip>using namespace std;double par[220][220];double dis[220];int vis[220],n;double ans;struct node{    int x,y;};node nodes[202];void init(){    for(int i=1; i<=n; i++)        for(int j=1; j<=n; j++)            if(i!=j)            {                double tmp=sqrt((double)((nodes[i].x-nodes[j].x)*(nodes[i].x-nodes[j].x)+(nodes[i].y-nodes[j].y)*(nodes[i].y-nodes[j].y)));                par[i][j]=tmp;                par[j][i]=tmp;            }            else            {                par[i][j]=0;                par[j][i]=0;            }    memset(vis,0,sizeof(vis));}void dj(){    vis[1]=1;    for(int i=2; i<=n; i++)        dis[i]=par[1][i];    dis[1]=0;    while(1)    {        int v=-1;        double min_dis=10000000;        for(int i=1; i<=n; i++)        {            if(!vis[i] && min_dis>dis[i])            {                min_dis=dis[i];                v=i;            }        }        if(v==-1)        {            ans=dis[2];            return ;        }        vis[v]=1;        for(int i=1; i<=n; i++)            if(!vis[i] && dis[i]>max(dis[v],par[v][i] ))                dis[i]=max(dis[v],par[v][i] );    }}int main(){    int t=0;    while(cin>>n,n)    {        for(int i=1; i<=n; i++)        {            cin>>nodes[i].x>>nodes[i].y;        }        init();        dj();        cout<<"Scenario #"<<++t<<endl<<"Frog Distance = "<<fixed<<setprecision(3)<<ans<<endl<<endl;    }    return 0;}

4.弗洛伊德算法拓展:uva104

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int n;double dp[25][25][25];//dp[i][j][p]记录i到j且遍历的国家数为p的乘积int path[25][25][25];//path[i][j][p]记录i到j的第p个遍历的国家void print(int i,int j,int p)//打印i到j的第p个遍历的国家{    if(p==0)        printf("%d",i);    else    {        print(i,path[i][j][p],p-1);        printf(" %d",j);    }}void floyd(){    for(int p=1;p<n;p++)    {        for(int k=1;k<=n;k++)            for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)            if(dp[i][k][p]*dp[k][j][1]>dp[i][j][p+1])        {            dp[i][j][p+1]=dp[i][k][p]*dp[k][j][1];            path[i][j][p+1]=k;        }        for(int i=1;i<=n;i++)            if(dp[i][i][p+1]>1.01)        {            print(i,i,p+1);            return ;        }    }    printf("no arbitrage sequence exists");}int main(){    while(scanf("%d",&n)!=EOF)    {        memset(path,0,sizeof(path));        memset(dp,0,sizeof(dp));        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++)            if(i!=j)            {                scanf("%lf",&dp[i][j][1]);                path[i][j][1]=i;            }           floyd();           printf("\n");    }    return 0;}
原创粉丝点击