首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Sightseeing poj 求最短招法量和最短路长度加1的路的数量 经典题

2012-09-09 
Sightseeing poj 求最短路数量和最短路长度加1的路的数量 经典题!/*经典的dij统计路的数量的好题!增加一维

Sightseeing poj 求最短路数量和最短路长度加1的路的数量 经典题!

/*经典的dij统计路的数量的好题!增加一维表示最短和次短两个状态。0表示最短,1表示次短。邻接表和邻接阵结合使用。加快速度。在统计数量的部分有详细的注释。*/#include <stdio.h>#include <cstring>const int maxm=10001;const int maxn=1001;const int inf=1<<30;struct edge{    int from,to,next,w;}e[maxm];int head[maxn];int dist[maxn][2],cnt[maxn][2],vis[maxn][2];int t,n,m,top;void add(int i,int j,int w){    e[top].from=i;    e[top].to=j;    e[top].w=w;    e[top].next=head[i];    head[i]=top++;}int main(){    int u,v,w,s,end;    scanf("%d",&t);    while(t--)    {        top=0;        scanf("%d%d",&n,&m);        memset(head,-1,sizeof(head));        memset(vis,false,sizeof(vis));        while(m--)        {            scanf("%d%d%d",&u,&v,&w);            add(u,v,w);        }        scanf("%d%d",&s,&end);        memset(dist,0x7f,sizeof(dist));        memset(cnt,0,sizeof(cnt));        dist[s][0]=0;        cnt[s][0]=1;        for(int i=1;i<2*n;i++)//循环2n-1次,最短路n-1次,次短路n次        {            int min=inf;            int k,flag;            for(int j=1;j<=n;j++)            {                if(!vis[j][0]&&dist[j][0]<min)                min=dist[j][0],k=j,flag=0;                if(!vis[j][1]&&dist[j][1]<min)                min=dist[j][1],k=j,flag=1;            }            if(min==inf) break;            vis[k][flag]=true;            for(int j=head[k];j!=-1;j=e[j].next)            {                int u=e[j].to;//用邻接表遍历和k相连的所有节点,数据较大,这样速度较快                int val=min+e[j].w;                if(dist[u][0]>val)//此条件为更新最短路                {                    dist[u][1]=dist[u][0];//此时原先的最短路dist[u][0]现在变为次短,将其赋值给dist[u][1].                    cnt[u][1]=cnt[u][0];                    dist[u][0]=val;//更新最短路的值                    cnt[u][0]=cnt[k][flag];//直接更新最短路的数量                }                else if(dist[u][0]==val)//如果当前路径长度和最短路径相同,则最短路径长度++                cnt[u][0]+=cnt[k][flag];                else if(dist[u][1]>val)//当前路径长度无法更新最短路,但是可以更新次短路。就进行更新。                {                    dist[u][1]=val;                    cnt[u][1]=cnt[k][flag];                }                else if(dist[u][1]==val)//同上。                cnt[u][1]+=cnt[k][flag];            }        }        if(dist[end][1]-1==dist[end][0])        printf("%d\n",cnt[end][1]+cnt[end][0]);        else printf("%d\n",cnt[end][0]);    }    return 0;}

热点排行