• poj3463 Sightseeing(dijkstra)


    题目链接:http://poj.org/problem?id=3463

    题意:求最短路和比最短路大1的路条数。

    思路:这里只要把dijkstra变形就可以了。一般的dijkstra只是求最短路。而这里求出最短路和次短路 和他们的条数。

    思路是一样的,找到一条没访问的最小边,再通过它更新最短距离。

    这里也是,只不这里要找2*n-1次  没访问过的最小边   ,因为要找到出起点外 n-1个点最短路 和所以n个点的次短路。

    再更新,这里的更新条件就不只是一个情况了。有四种:(假设  minx是目前找到的最小边,v是需要更新的点,w是到更新点v的边权 )

    d[v][0]存最短路值,d[v][1]存次短路值

    1. d[v][0]>minx+w       更新最短距离(但是记得更新次短距离,次短距离一定大于d[v][0],当d[v][0]更新成minx+w时,次短距离更新成原来的d[v][0])

    2.d[v][0]==minx+w     找到相同最短距离,更新最短条数

    3.d[v][1]>minx+w       更新次短距离

    3.d[v][1]==minx+w     找到相同次短距离,更新次短条数

    详情看代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn=1100;
    const int maxm=10100;
    struct node{
        int u,v,w,nxt;
    }e[maxm];
    int d[maxn][2],ans[maxn][2],vis[maxn][2],head[maxn];
    int n,m,st,ed,cnt;
    //d[][0]最短距离,d[][1]次短距离,ans[][]最短,次短条数 
    void add(int u,int v,int w)
    {
        e[cnt]={u,v,w,head[u]};
        head[u]=cnt++;
    }
    
    int dij()
    {
        memset(d,0x3f,sizeof(d));
        memset(vis,0,sizeof(vis));
        memset(ans,0,sizeof(ans));
        ans[st][0]=1;
        d[st][0]=0;
        for(int i=1;i<2*n;i++)
        {
            int minx=inf,u,flag;
            for(int j=1;j<=n;j++)
            {
                if(!vis[j][0]&&minx>d[j][0])
                {
                    minx=d[j][0];
                    u=j;
                    flag=0;
                }
                else if(!vis[j][1]&&minx>d[j][1])
                {
                    minx=d[j][1];
                    u=j;
                    flag=1;
                }
            }
            //cout<<u<<endl;
            if(minx==inf) break;
            vis[u][flag]=1;
            for(int j=head[u];j!=-1;j=e[j].nxt)
            {
                int v=e[j].v;
                int w=e[j].w;
                if(d[v][0]>minx+w)//1
                {
                    ans[v][1]=ans[v][0];
                    d[v][1]=d[v][0];
                    d[v][0]=minx+w;
                    ans[v][0]=ans[u][flag];
                }
                else if(d[v][0]==minx+w)//2
                    ans[v][0]+=ans[u][flag];
                else if(d[v][1]>minx+w)//3
                {
                    d[v][1]=minx+w;
                    ans[v][1]=ans[u][flag];
                }
                else if(d[v][1]==minx+w)//4
                    ans[v][1]+=ans[u][flag];
            }
        }
        int res=ans[ed][0];
        //cout<<d[ed][0]<<' '<<d[ed][1]<<endl; 
        if(d[ed][1]==d[ed][0]+1)
            res+=ans[ed][1];
        printf("%d
    ",res);
    }
    
    int main()
    {
        int t,u,v,w;
        scanf("%d",&t);
        while(t--)
        {
            cnt=0;
            memset(head,-1,sizeof(head));
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
            }
            scanf("%d%d",&st,&ed);
            dij();
        }
        return 0;
    }
  • 相关阅读:
    jquery及相关兼容插件的版本搭配
    jquery IE7 下报错:SCRIPT257: 由于出现错误 80020101 而导致此项操作无法完成
    兼顾php和jquery新版本的checkbox的写法
    jquery.validate动态更改校验规则 【转】
    Google的10大座右铭
    用jQuery屏蔽掉按回车键时提交表单
    sizeof()和strlen()在求字符串长度时的差别
    Matlab使用心得
    C++ 数据类型及相关问题 及输出精度控制
    原生javascript满屏上下滚动
  • 原文地址:https://www.cnblogs.com/xiongtao/p/11206820.html
Copyright © 2020-2023  润新知