优先队列优化的求最短路和次短路条数以及长度的模板

来源:互联网 发布:网络盒子破解软件 编辑:程序博客网 时间:2024/05/26 09:55
//无向图版本struct Edge{    int to;    int w;};struct node{    int v;    int dist;    int mark;    bool friend operator <(const node &a,const node &b)    {        if(a.dist!=b.dist)            return a.dist>b.dist;        return a.v>b.v;    }};priority_queue<node> Q;vector<Edge>gra[N];int dp[N][3];//1是最短路条数;2是次短路条数int vis[N][3];int dis[N][3];//1是最短路的长度;2是次短路的长度int n,m;void init(){    for(int i=0; i<N; i++)    {        dp[i][1]=dp[i][2]=0;        vis[i][1]=vis[i][2]=0;        dis[i][1]=dis[i][2]=INF;    }}void addedge(int u,int v,int w){    gra[u].push_back((Edge){v,w});    gra[v].push_back((Edge){u,w});}void Dijstra(int st,int ed){    dis[st][1]=0;    dp[st][1]=1;    node q,p;    p.dist=0;    p.mark=1;    p.v=st;    Q.push(p);    while(!Q.empty())    {        q=Q.top();        Q.pop();        if(vis[q.v][q.mark])            continue;        vis[q.v][q.mark]=1;        for(int i=0; i<(int)gra[q.v].size(); i++)        {            int vv=gra[q.v][i].to;            ll ww=gra[q.v][i].w;            if(!vis[vv][1]&&dis[vv][1]>q.dist+ww)//比最短路短,更新最短路            {                if(dis[vv][1]!=INF)                {                    dis[vv][2]=dis[vv][1];                    dp[vv][2]=dp[vv][1];                    p.dist=dis[vv][2];                    p.mark=2;                    p.v=vv;                    Q.push(p);                }                dis[vv][1]=q.dist+ww;                dp[vv][1]=dp[q.v][q.mark];                p.mark=1;                p.dist=dis[vv][1];                p.v=vv;                Q.push(p);            }            else if(!vis[vv][1]&&dis[vv][1]==q.dist+ww)//等于最短路,更新条数            {                dp[vv][1]+=dp[q.v][q.mark];            }            else if(!vis[vv][2]&&dis[vv][2]>q.dist+ww)//比次短路短,更新次短路            {                dis[vv][2]=q.dist+ww;                dp[vv][2]=dp[q.v][q.mark];                p.mark=2;                p.dist=dis[vv][2];                p.v=vv;                Q.push(p);            }            else if(!vis[vv][2]&&dis[vv][2]==q.dist+ww)//等于次短路,更新条数            {                dp[vv][2]+=dp[q.v][q.mark];            }        }    }}int main(){    int T;    scanf("%d",&T);    while(T--)    {        init();        for(int i=0;i<N;i++)          gra[i].clear();        scanf("%d%d",&n,&m);//n个点;m条边        int u,v,w;        for(int i=0; i<m; i++)        {            scanf("%d%d%d",&u,&v,&w);            addedge(u,v,w);        }        Dijstra(1,n);//1到n的最短路    }    return 0;}

参考例题:
HDU6181(无向图),HDU3191( 有向图)

阅读全文
0 0