zoukankan      html  css  js  c++  java
  • 备战快速复习--day12

    几个要点

    • 初始化d[s]=0,c[s]=0
    • 每次找到u以后vis[u]=true
    • 使用g[x][y]>0判断有没有边,那么就需要初始化为0,不然有的评测默认不是0.
    #include<stdio.h>
    #include<iostream>
    #include<vector>
    #include<string.h>
    using namespace std;
    int st,ed,n,m;
    int d[1000],c[1000];
    int G[1000][1000]={0},cost[1000][1000]={0};
    bool vis[1000]={false};
    vector<int>pre[1000];
    const int INF=100000;
    void Dijkstra(int s)
    {
        fill(d,d+n,INF);
        fill(c,c+n,INF);
        d[s]=0;
        c[s]=0;
        for(int i=0;i<=n-1;i++)
            pre[i].push_back(i);
        for(int i=0;i<=n-1;i++)
        {
            int u=-1;
            int minnum=INF;
            for(int j=0;j<=n-1;j++)
            {
                if(vis[j]==false && d[j]<minnum)
                {
                    minnum=d[j];
                    u=j;
                }
            }
            if(u==-1)
                return;
            vis[u]=true;
            for(int j=0;j<=n-1;j++)
            {
                if(vis[j]==false && G[u][j]>0)
                {
                    if(d[j]>d[u]+G[u][j])
                    {
                        d[j]=d[u]+G[u][j];
                        c[j]=c[u]+cost[u][j];
                        pre[j].clear();
                        pre[j].push_back(u);
                        //printf("j:%d u:%d part1:%d
    ",j,u,pre[j][0]);
                    }
                    else if(d[j]==d[u]+G[u][j] && c[j]>c[u]+cost[u][j])
                    {
                        c[j]=c[u]+cost[u][j];
                        pre[j].clear();
                        pre[j].push_back(u);
                        //printf("j:%d u:%d part2:%d
    ",j,u,pre[j][0]);
                    }
                }
            }
        }
    }
    void shuchu(int s,int e)
    {
        //printf("here:%d %d
    ",s,e);
        if(s==e)
        {
            printf("%d ",s);
            return;
        }
        shuchu(s,pre[e][0]);
        printf("%d ",e);
    }
    int main()
    {
        scanf("%d %d %d %d",&n,&m,&st,&ed);
        int temp1,temp2,temp3,temp4;
        for(int i=0;i<=m-1;i++)
        {
            scanf("%d %d %d %d",&temp1,&temp2,&temp3,&temp4);
            G[temp1][temp2]=temp3;
            G[temp2][temp1]=temp3;
            cost[temp1][temp2]=temp4;
            cost[temp2][temp1]=temp4;
        }
        Dijkstra(st);
        /*for(int i=0;i<=n-1;i++)
            printf("%d ",pre[i][0]);*/
        shuchu(st,ed);
        printf("%d %d
    ",d[ed],c[ed]);
        return 0;
    }
    dijkstra直接最优子结构
    • 别忘了vector倒叙访问,如果不用迭代器,i=v.size()-1,end是给it用的
    • 注意在根据d变化修改vector的时候不要忘了本来的d修改
    • dfs中每次插入temp的是当前e点,sum中的是即将进入的下一轮e和当前e
    • 加完了别忘了删除
    #include<stdio.h>
    #include<string.h>
    #include<vector>
    using namespace std;
    int n,m,st,ed;
    int G[1000][1000]={0},cost[1000][1000]={0};
    int d[1000];
    bool vis[1000]={false};
    const int INF=10000;
    vector<int>pre[1000];
    void Dijkstra(int s)
    {
        fill(d,d+n,INF);
        d[s]=0;
        for(int i=0;i<=n-1;i++)
        {
            int u=-1;
            int minnum=10000;
            for(int j=0;j<=n-1;j++)
            {
                if(vis[j]==false && d[j]<minnum)
                {
                    u=j;
                    minnum=d[j];
                }
            }
            if(u==-1)
                return;
            vis[u]=true;
            for(int j=0;j<=n-1;j++)
            {
                if(vis[j]==false && G[u][j]>0)
                {
                    if(d[j]>d[u]+G[u][j])
                    {
                        d[j]=d[u]+G[u][j];
                        //printf("no1 :%d
    ",j);
                        pre[j].clear();
                        pre[j].push_back(u);
                    }
                    else if(d[j]==d[u]+G[u][j])
                    {
                        //printf("no2");
                        pre[j].push_back(u);
                    }
                }
            }
        }
    }
    int nowsum=10000;
    vector<int>ansroute;
    vector<int>temproute;
    void DFS(int s,int e,int sum)
    {
        if(s==e)
        {
            if(sum<nowsum)
            {
                nowsum=sum;
                ansroute=temproute;
            }
            return;
        }
        for(int i=0;i<=pre[e].size()-1;i++)
        {
            temproute.push_back(e);
            DFS(s,pre[e][i],sum+cost[pre[e][i]][e]);
            temproute.erase(temproute.end()-1);
        }
    }
    int main()
    {
        scanf("%d %d %d %d",&n,&m,&st,&ed);
        for(int i=0;i<=m-1;i++)
        {
            int temp1,temp2,temp3,temp4;
            scanf("%d %d %d %d",&temp1,&temp2,&temp3,&temp4);
            G[temp1][temp2]=G[temp2][temp1]=temp3;
            cost[temp1][temp2]=cost[temp2][temp1]=temp4;
        }
        for(int i=0;i<=n-1;i++)
            pre[i].push_back(i);
        Dijkstra(st);
        DFS(st,ed,0);
        ansroute.push_back(st);
        for(int i=ansroute.size()-1;i>=0;i--)
            printf("%d ",ansroute[i]);
        printf("%d %d",d[ed],nowsum);
        return 0;
    }
    Dijkstra+dfs

     凡是说马路,没有意外都是无向图,要双向赋值。

    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    servlet
    过滤器
    拦截器
    logback
    hibernate(1)
    函数的关键字参数
    函数的不定长参数
    打印星形三角
    九九乘法表
    udp客户端收发数据流程
  • 原文地址:https://www.cnblogs.com/tingxilin/p/12466356.html
Copyright © 2011-2022 走看看