poj3463Sightseeing(最短路条数+次短路条数)

来源:互联网 发布:怎样注册中文.手机域名 编辑:程序博客网 时间:2024/05/21 19:46
//poj 3463//次短路长度为最短路长度+1//最短路条数+次短路条数//分四种情况更新,练习了dijstra的更新//路条数用加法原理更新#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;const int N=10100,M=100100;const int INF=0x3fffffff;#define clr(a) memset(a,0,sizeof(a))int cnt;struct Node{    int u,v,w,next;}edge[2*M];int head[N];void addedge(int u,int v,int w){    edge[cnt].u=u;edge[cnt].v=v;edge[cnt].w=w;edge[cnt].next=head[u];    head[u]=cnt++;}void init(){    cnt=0;    memset(head,-1,sizeof(head));}bool vis[N][2];//int dp[N][2];//路径条数int dis[N][2];//0 最短,1 次短int dijstra(int src,int des,int n){    clr(vis);clr(dp);    for(int i=0;i<=n;i++)        dis[i][0]=dis[i][1]=INF;    dis[src][0]=0;    dp[src][0]=1;    for(int i=1;i<2*n;i++){//n-1次是求最短路的,n次求次短路的        int mini=INF;//维护某点到起点的最小值        int mark=-1;        int kind=-1;        for(int j=1;j<=n;j++){//选择未扩展过的最短的点进行扩展            if(!vis[j][0]&&dis[j][0]<mini){                mini=dis[j][0];                mark=j;                kind=0;            }            else if(!vis[j][1]&&dis[j][1]<mini){                mini=dis[j][1];                mark=j;                kind=1;            }        }        if(mini==INF)break;        vis[mark][kind]=1;//表示此点已经扩展过        for (int j=head[mark]; j!=-1; j=edge[j].next) {            int v=edge[j].v;            int w=edge[j].w;            if(mini+w<dis[v][0]){//距离小于v到起点的最小距离。                dis[v][1]=dis[v][0];//最小距离变为次小距离                dis[v][0]=mini+w;//更新最小距离                dp[v][1]=dp[v][0];//最小距离条数变为次小距离条数                dp[v][0]=dp[mark][kind];//更新最小距离条数            }            else if(mini+w==dis[v][0]){                dp[v][0]+=dp[mark][kind];            }            else if(mini+w<dis[v][1]){//介于最小与次小之间,更新次小。                dis[v][1]=mini+w;                dp[v][1]=dp[mark][kind];            }            else if(mini+w==dis[v][1]){                dp[v][1]+=dp[mark][kind];            }        }        }    if(dis[des][0]+1==dis[des][1])        return dp[des][0]+dp[des][1];    return dp[des][0];}int main(){    int n,m;    int t;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);            init();            for(int i=0;i<m;i++){                int u,v,w;                scanf("%d%d%d",&u,&v,&w);                addedge(u,v,w);                }            int s,t,k;            scanf("%d%d",&s,&t);            printf("%d\n",dijstra(s,t,n));        }    return 0;}

0 0
原创粉丝点击