POJ3463

来源:互联网 发布:石家庄众人网络靠谱吗 编辑:程序博客网 时间:2024/04/30 01:01

Problem: Sightseeing
Description: 给你一个有向图。现在问你最短路的条数和比最短路长度大一的路径条数一共是多少。
Solution: 通过这个题目,熟悉了求解最短路和次短路的长度和条数的方法,真正理解了迪杰斯特拉。我们在用迪杰斯特拉更新dis的时候要判断小于最短路、等于最短路、小于次短路、等于次短路的情况。仔细画个图就理解了。看代码吧。哦,对了,这个题目是的起点是从1开始的,而我的代码是从0开始的。因此一开始错了很久。
Code(C++):

#include <stdio.h>#include <string.h>const int M=1005;const int E=10005;const int INF=0x3f3f3f3f;typedef struct tagNode{    int from,to;    int c;    int next;    tagNode(){    }    tagNode(int from,int to,int c,int next){        this->from=from;        this->to=to;        this->c=c;        this->next=next;    }}Node;int n,m;int src,des;Node edge[E];int head[M];int dis[2][M];int used[2][M];int cnt[2][M];int dij(int src){    memset(used,false,sizeof(used));    memset(cnt,0,sizeof(cnt));    memset(dis,INF,sizeof(dis));    dis[0][src]=0;    cnt[0][src]=1;    for(int i=0;i<2*n-1;i++){        int tmp=INF,pos;        int f;        for(int j=0;j<n;j++)            if(!used[0][j]&&dis[0][j]<tmp)                f=0,tmp=dis[0][j],pos=j;            else if(!used[1][j]&&dis[1][j]<tmp)                f=1,tmp=dis[1][j],pos=j;        if(tmp>=INF)            break;        used[f][pos]=true;        for(int j=head[pos];j+1;j=edge[j].next){            int to=edge[j].to;            if(dis[0][to]>tmp+edge[j].c)                dis[1][to]=dis[0][to],                dis[0][to]=tmp+edge[j].c,                cnt[1][to]=cnt[0][to],                cnt[0][to]=cnt[f][pos];            else if(dis[0][to]==tmp+edge[j].c)                cnt[0][to]+=cnt[f][pos];            else if(dis[1][to]>tmp+edge[j].c)                dis[1][to]=tmp+edge[j].c,                cnt[1][to]=cnt[f][pos];            else if(dis[1][to]==tmp+edge[j].c)                cnt[1][to]+=cnt[f][pos];        }    }    int ans=cnt[0][des];    if(dis[0][des]+1==dis[1][des])        ans+=cnt[1][des];    return ans;}void add_edge(int from,int to,int c,int index){    edge[index]=Node(from,to,c,head[from]);    head[from]=index;}int main(){    int N;    for(scanf("%d",&N);N--;){        memset(head,-1,sizeof(head));        scanf("%d%d",&n,&m);        int from,to,c;        for(int i=0;i<m;i++){            scanf("%d%d%d",&from,&to,&c);            add_edge(--from,--to,c,i);        }        scanf("%d%d",&src,&des);        --src,--des;        int ans=dij(src);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击