• 数据结构大实习——图论


    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    const int maxn=510;
    const int inf=10000;
    
    struct node
    {
        int type,len;//type为类型,len为道路长度
    }map[maxn][maxn];
    
    bool vis[maxn];//标记当前节点是否来过
    
    void fiset(int n)//初始化数组
    {
        for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                map[i][j].len=inf;
            }
            vis[i]=0;
        }
        return ;
    }
    
    int dou(int x)//计算x的平方
    {
        return x*x;
    }
    
    int dij(int n)//迪杰斯特拉算法
    {
        int dist[maxn],small[maxn];//small数组记录到当前节点连续走过的小道长度
        for(int i=1;i<=n;i++)
        {
            if(map[1][i].type==0)
            {
                small[i]=0;
                dist[i]=map[1][i].len;
            }
            else
            {
                small[i]=map[1][i].len;
                dist[i]=dou(map[1][i].len);
            }
        }
        vis[1]=1;
        for(int i=2;i<=n;i++)
        {
            int minn=inf,u;
            for(int j=1;j<=n;j++)
            {
                if(!vis[j]&&minn>dist[j])
                {
                    minn=dist[j];
                    u=j;
                }
            }
            vis[u]=1;
            for(int j=1;j<=n;j++)
            {
                if(vis[j])continue;
                if(map[u][j].type==0)//判断为大道,进行正常的松弛操作
                {
                    if(dist[u]+map[u][j].len<dist[j])
                    {
                        small[j]=0;
                        dist[j]=dist[u]+map[u][j].len;
                    }
                }
                else//判断为小道则比较连续走小道的疲劳度再进行比较
                {
                    if(dist[j]>(dist[u]-dou(small[u])+dou(small[u]+map[u][j].len)))
                    {
                        small[j]=small[u]+map[u][j].len;
                        dist[j]=dist[u]-dou(small[u])+dou(small[u]+map[u][j].len);
                    }
                }
            }
        }
        return dist[n];//最终返回到达n点的最小疲劳度
    }
    
    int main()
    {
        int n,m;
        int t,a,b,c;
        while(cin>>n>>m)
        {
            fiset(n);
            for(int i=0;i<m;i++)
            {
                map[i+1][i+1].len=0;//将节点到自身的长度初始化为0
                cin>>t>>a>>b>>c;
                map[a][b].type=t;
                map[b][a].type=t;
                map[a][b].len=map[b][a].len=c;
            }
            cout<<dij(n)<<endl;
        }
        return 0;
    }
    
    /*
    6 7
    1 1 2 3
    1 2 3 2
    0 1 3 30
    0 3 4 20
    0 4 5 30
    1 3 5 6
    1 5 6 1
    */
    

      

  • 相关阅读:
    POJ 2502 Subway(最短路径)
    HDU 1430 魔板
    HDU 1043 POJ 1077 八数码问题
    POJ 2576 Tug of War 随机算法(非正规解法)
    什么是COM
    6.0的版本的 tc,不支持大漠对象做数组吗?
    Q键连发。按住Q键则连发。松开则停止1。
    Q键连发。按住Q键 则连发。松开则停止2。
    特殊符号。
    僵尸_另类的生命体。
  • 原文地址:https://www.cnblogs.com/wyhbadly/p/10132654.html
Copyright © 2020-2023  润新知