zoukankan      html  css  js  c++  java
  • hdu 3191 次短路的长度和个数

    http://acm.hdu.edu.cn/showproblem.php?pid=3191

    求次短路的长度和个数

    相关分析在这里http://blog.csdn.net/u012774187/article/details/40681515

    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define clr1(x) memset(x,-1,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int inf = 0x3fffffff;
    const LL _inf = 1e18;
    const int maxn = 55,maxm = 10005;
    struct edge{
        int v,w,next;
        edge(){};
        edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
    }e[maxn*maxn*2];
    int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
    int n,m,ecnt;
    void init()
    {
        clr1(head);
        ecnt = 0;
        for(int i = 1;i <= maxn;++i)
            dist[i][0] = dist[i][1] = inf;
        //fill(dist,dist+maxn*2,inf);
        clr0(inq),clr0(cnt);
    }
    void add(int u,int v,int w)
    {
        e[ecnt] = edge(v,w,head[u]);
        head[u] = ecnt++;
    //    e[ecnt] = edge(u,w,head[v]);
    //    head[v] = ecnt++;
    }
    typedef pair<int,int> p2;
    struct cmp {
         bool operator() (const p2 &a, const p2 &b)
         {
            if(dist[a.first][a.second] != dist[b.first][b.second])
                return dist[a.first][a.second] > dist[b.first][b.second];
            else
                return a.first > b.first;
         }
    };
    void spfa(int src,int dst)
    {
        priority_queue<p2 , vector<p2> , cmp> q;
        q.push(make_pair(src,0));
        dist[src][0] = 0,cnt[src][0] = 1;
        while(!q.empty()){
            int u = q.top().first,flag = q.top().second;
            q.pop();
            if(inq[u][flag])    continue;
            inq[u][flag] = 1;
            for(int i = head[u];i != -1;i = e[i].next){
                int v = e[i].v,w = e[i].w;
                if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){
                    if(dist[v][0] != inf){
                        dist[v][1] = dist[v][0];
                        cnt[v][1] = cnt[v][0];
                        q.push(make_pair(v,1));
                    }
                    dist[v][0] = dist[u][flag] + e[i].w;
                    cnt[v][0] = cnt[u][flag];
    
                    q.push(make_pair(v,0));
                }else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){
                    cnt[v][0] += cnt[u][flag];
                }else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){
                    dist[v][1] = dist[u][flag] + e[i].w;
                    cnt[v][1] = cnt[u][flag];
    
                    q.push(make_pair(v,1));
                }else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){
                    cnt[v][1] += cnt[u][flag];
                }
            }
        }
        printf("%d %d
    ",dist[dst][1],cnt[dst][1]);
    }
    
    int main(){
        int u,v,w,s,t;
        while(~RD2(n,m)){
            RD2(s,t);s++,t++;
            init();
            while(m--){
                RD3(u,v,w);u++,v++;
                add(u,v,w);
            }
            spfa(s,t);
        }
        return 0;
    }

    上面是错误代码

    经过筛查,发现是

    if(dist[a.first][a.second] != dist[b.first][b.second])
                return dist[a.first][a.second] > dist[b.first][b.second];

    有问题,因为不同的路径到达同一个点的同一个状态的值不一样,所有比较和更新穿插在一起就会出错了

    可是每次更新dist数组都是向小了更新,所以不应该有影响啊..?


    以下是AC代码,谁能清楚一点地告诉为啥上面的程序就不对呢?

    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define clr1(x) memset(x,-1,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int inf = 0x3fffffff;
    const LL _inf = 1e18;
    const int maxn = 55,maxm = 10005;
    struct edge{
        int v,w,next;
        edge(){};
        edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
    }e[maxn*maxn*2];
    int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
    int n,m,ecnt;
    struct node{
        int v,flag,dis;
        node(int a,int b,int c):v(a),flag(b),dis(c){};
        bool operator < (const node & a) const{
            if(a.dis == dis)
                return a.v < v;
            return a.dis < dis;
        }
    };
    void init()
    {
        clr1(head);
        ecnt = 0;
        for(int i = 0;i <= n;++i)
            dist[i][0] = dist[i][1] = inf;
        //fill(dist,dist+maxn*2,inf);
        clr0(inq),clr0(cnt);
    }
    void add(int u,int v,int w)
    {
        e[ecnt] = edge(v,w,head[u]);
        head[u] = ecnt++;
    //    e[ecnt] = edge(u,w,head[v]);
    //    head[v] = ecnt++;
    }
    void spfa(int src,int dst)
    {
        priority_queue<node> q;
        q.push(node(src,0,0));
        dist[src][0] = 0,cnt[src][0] = 1;
        while(!q.empty()){
            int u = q.top().v,flag = q.top().flag,dis = q.top().dis;
            q.pop();
            if(inq[u][flag])    continue;
            inq[u][flag] = 1;
            for(int i = head[u];i != -1;i = e[i].next){
                int v = e[i].v,w = e[i].w;
                if(!inq[v][0] && dist[v][0] > dis + e[i].w){
                    if(dist[v][0] != inf){
                        dist[v][1] = dist[v][0];
                        cnt[v][1] = cnt[v][0];
                        q.push(node(v,1,dist[v][1]));
                    }
                    dist[v][0] = dis + e[i].w;
                    cnt[v][0] = cnt[u][flag];
    
                    q.push(node(v,0,dist[v][0]));
                }else if(!inq[v][0] && dist[v][0] == dis + e[i].w){
                    cnt[v][0] += cnt[u][flag];
                }else if(!inq[v][1] && dist[v][1] > dis + e[i].w){
                    dist[v][1] = dis + e[i].w;
                    cnt[v][1] = cnt[u][flag];
    
                    q.push(node(v,1,dist[v][1]));
                }else if(!inq[v][1] && dist[v][1] == dis+ e[i].w){
                    cnt[v][1] += cnt[u][flag];
                }
            }
        }
        printf("%d %d
    ",dist[dst][1],cnt[dst][1]);
    }
    
    int main(){
        int u,v,w,s,t;
        while(~RD2(n,m)){
            RD2(s,t);s++,t++;
            init();
            while(m--){
                RD3(u,v,w);u++,v++;
                add(u,v,w);
            }
            spfa(s,t);
        }
        return 0;
    }
    

    AC代码2

    #pragma comment(linker, "/STACK:36777216")
    #pragma GCC optimize ("O2")
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <map>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define RD(x) scanf("%d",&x)
    #define RD2(x,y) scanf("%d%d",&x,&y)
    #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define clr0(x) memset(x,0,sizeof(x))
    #define clr1(x) memset(x,-1,sizeof(x))
    #define eps 1e-9
    const double pi = acos(-1.0);
    typedef long long LL;
    typedef unsigned long long ULL;
    const int modo = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    const int inf = 0x3fffffff;
    const LL _inf = 1e18;
    const int maxn = 55,maxm = 10005;
    struct edge{
        int v,w,next;
        edge(){};
        edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
    }e[maxn*maxn*2];
    int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
    int n,m,ecnt;
    struct node{
        int v,flag,dis;
        node(int a,int b,int c):v(a),flag(b),dis(c){};
        bool operator < (const node & a) const{
            if(a.dis == dis)
                return a.v < v;
            return a.dis < dis;
        }
    };
    void init()
    {
        clr1(head);
        ecnt = 0;
        for(int i = 0;i <= n;++i)
            dist[i][0] = dist[i][1] = inf;
        //fill(dist,dist+maxn*2,inf);
        clr0(inq),clr0(cnt);
    }
    void add(int u,int v,int w)
    {
        e[ecnt] = edge(v,w,head[u]);
        head[u] = ecnt++;
    //    e[ecnt] = edge(u,w,head[v]);
    //    head[v] = ecnt++;
    }
    void spfa(int src,int dst)
    {
        priority_queue<node> q;
        q.push(node(src,0,0));
        dist[src][0] = 0,cnt[src][0] = 1;
        while(!q.empty()){
            int u = q.top().v,flag = q.top().flag;//dis = q.top().dis;
            q.pop();
            if(inq[u][flag])    continue;
            inq[u][flag] = 1;
            for(int i = head[u];i != -1;i = e[i].next){
                int v = e[i].v,w = e[i].w;
                if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){
                    if(dist[v][0] != inf){
                        dist[v][1] = dist[v][0];
                        cnt[v][1] = cnt[v][0];
                        q.push(node(v,1,dist[v][1]));
                    }
                    dist[v][0] = dist[u][flag] + e[i].w;
                    cnt[v][0] = cnt[u][flag];
    
                    q.push(node(v,0,dist[v][0]));
                }else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){
                    cnt[v][0] += cnt[u][flag];
                }else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){
                    dist[v][1] = dist[u][flag] + e[i].w;
                    cnt[v][1] = cnt[u][flag];
    
                    q.push(node(v,1,dist[v][1]));
                }else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){
                    cnt[v][1] += cnt[u][flag];
                }
            }
        }
        printf("%d %d
    ",dist[dst][1],cnt[dst][1]);
    }
    
    int main(){
        int u,v,w,s,t;
        while(~RD2(n,m)){
            RD2(s,t);s++,t++;
            init();
            while(m--){
                RD3(u,v,w);u++,v++;
                add(u,v,w);
            }
            spfa(s,t);
        }
        return 0;
    }
    



    #pragma comment(linker, "/STACK:36777216")#pragma GCC optimize ("O2")#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <string>#include <queue>#include <map>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))#define clr1(x) memset(x,-1,sizeof(x))#define eps 1e-9const double pi = acos(-1.0);typedef long long LL;typedef unsigned long long ULL;const int modo = 1e9 + 7;const int INF = 0x3f3f3f3f;const int inf = 0x3fffffff;const LL _inf = 1e18;const int maxn = 55,maxm = 10005;struct edge{ int v,w,next; edge(){}; edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};}e[maxn*maxn*2];int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短int n,m,ecnt;void init(){ clr1(head); ecnt = 0; for(int i = 0;i < maxn;++i) dist[i][0] = dist[i][1] = inf; //fill(dist,dist+maxn*2,inf); clr0(inq),clr0(cnt);}void add(int u,int v,int w){ e[ecnt] = edge(v,w,head[u]); head[u] = ecnt++;// e[ecnt] = edge(u,w,head[v]);// head[v] = ecnt++;}typedef pair<int,int> p2;struct cmp { bool operator() (const p2 &a, const p2 &b) { if(dist[a.first][a.second] != dist[b.first][b.second]) return dist[a.first][a.second] > dist[b.first][b.second]; else return a.first > b.first; }};void spfa(int src,int dst){ priority_queue<p2 , vector<p2> , cmp> q; q.push(make_pair(src,0)); dist[src][0] = 0,cnt[src][0] = 1; while(!q.empty()){ int u = q.top().first,flag = q.top().second; q.pop(); if(inq[u][flag]) continue; inq[u][flag] = 1; for(int i = head[u];i != -1;i = e[i].next){ int v = e[i].v,w = e[i].w; if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){ if(dist[v][0] != inf){ dist[v][1] = dist[v][0]; cnt[v][1] = cnt[v][0]; q.push(make_pair(v,1)); } dist[v][0] = dist[u][flag] + e[i].w; cnt[v][0] = cnt[u][flag]; q.push(make_pair(v,0)); }else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){ cnt[v][0] += cnt[u][flag]; }else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){ dist[v][1] = dist[u][flag] + e[i].w; cnt[v][1] = cnt[u][flag]; q.push(make_pair(v,1)); }else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){ cnt[v][1] += cnt[u][flag]; } } } printf("%d %d ",dist[dst][1],cnt[dst][1]);}int main(){ int u,v,w,s,t; while(~RD2(n,m)){ RD2(s,t);s++,t++; init(); while(m--){ RD3(u,v,w);u++,v++; add(u,v,w); } spfa(s,t); } return 0;}
  • 相关阅读:
    人月神话阅读笔记之一
    第一阶段冲刺站立会议报告——9
    第一阶段冲刺站立会议报告——8
    第一阶段冲刺站立会议报告——7
    第一阶段冲刺站立会议报告——6
    第一阶段冲刺站立会议报告——5
    第二阶段冲刺第一天
    寻找水王2
    构建之法阅读笔记05
    第十二周学习进度条
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4074377.html
Copyright © 2011-2022 走看看