HDU3191 次短路条数

来源:互联网 发布:维多利亚贝克汉姆知乎 编辑:程序博客网 时间:2024/05/01 15:10
/*    求s到t的最短路与次短路(这里要求只比最短路多1)的条数之和    联想到最小,次小的一种更新关系:    if(x<最小)更新最小,次小    else if(==最小)更新方法数    else if(x<次小)更新次小    else if(x==次小)更新方法数    同时记录s到u最短,次短路及方法数    用一个堆每次取最小的,更新完后再入堆    还是那个原理,第一次遇到的就是最优的,然后vi标记为真    方法数注意是加法原理,不是乘法    \    -- u -- v  所以是加法原理    /*///单开一个数组来记录数目//理解了一下。。。还要回去debug..//http://blog.csdn.net/u013368721/article/details/36682223#include<iostream>#include<cstring>#include<string.h>#include<cstdio>#include<cstdlib>#include<algorithm>#include<queue>#define maxm 200#define maxn 200#define MAXN 200#define inf 0x3f3f3fusing namespace std;int em;int head[maxn];bool vis[2][maxn];int d[maxn];int d2[maxn];int cnt[2][maxn];struct Edge{    int u,len,next;}edge[2*MAXN];void addEdge(int v,int w,int c){    edge[em].u=w;    edge[em].len=c;    edge[em].next=head[v];    head[v]=em;    em++;}struct Node{    int a;    int kind;    int len;    friend bool operator <(Node a,Node b)    {        if(a.len!=b.len)        return a.len>b.len;        return a.a>b.a;//过了,但是这里为什么要按字典序排序    }}start,v,tem;priority_queue <Node>q;//0为最短路,1为次短路。。kind为加入的边的种类??开数组保存void dij(int s,int t){    while(!q.empty()) q.pop();    for(int i=0;i<=t;i++)        d[i]=inf,d2[i]=inf,cnt[0][i]=0,cnt[1][i]=0;    memset(vis,false,sizeof(vis));    start.a=s;    start.kind=0;    start.len=0;    cnt[0][s]=1;d[s]=0;    q.push(start);    while(!q.empty())    {        v=q.top();        int u=v.a;        int dis=v.len;        int kind=v.kind;        q.pop();        if(vis[kind][u]) continue;        vis[kind][u]=1;        for(int i=head[u];~i;i=edge[i].next)        {            int vi=edge[i].u;            int tmp=dis+edge[i].len;        if(tmp<d[vi])        {            if(d[vi]<d2[vi])                {                    d2[vi]=d[vi];                    cnt[1][vi]=cnt[0][vi];                    tem.a=vi;                    tem.len=d2[vi];                    tem.kind=1;                    q.push(tem);                }                d[vi]=tmp;                cnt[0][vi]=cnt[0][u];                tem.a=vi;                tem.len=tmp;                tem.kind=0;                q.push(tem);        }        else if(tmp==d[vi])        {            cnt[0][vi]+=cnt[0][u];        }        else if(tmp<d2[vi])        {            d2[vi]=tmp;            cnt[1][vi]=cnt[kind][u];            tem.a=vi;            tem.len=d2[vi];            tem.kind=1;            q.push(tem);        }        else if(tmp==d2[vi])        {            cnt[1][vi]+=cnt[kind][u];        }        }    }    cout<<d2[t]<<" "<<cnt[1][t]<<endl;}int main(){//    freopen("input.txt","r",stdin);    int n,m,s,a,b,e,w;    while(scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)    {        memset(head,-1,sizeof(head));        em=0;        for(int i=1;i<=m;i++)        {            scanf("%d%d%d",&a,&b,&w);            addEdge(a,b,w);        }        dij(s,e);    }}

0 0
原创粉丝点击