poj 1847最短路

来源:互联网 发布:wifi网络测试工具 编辑:程序博客网 时间:2024/06/05 16:32



题意:n个点,电车从A到B。每个点可以到其它ki个点,但默认只通往给出的第一个点,如果要到其它点,必须改变轨道方向一次。问A到B最少改变几次轨道方向。



总结:裸裸的最短路,所以,狠狠的把Floyd, Bellman, Dijkstra, Spfa都给撸了一遍。一个字,爽!


一道裸体,题意比较坑,于是试着写了一发dij的优先队列优化(V*log(E))和flyd。


#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<vector>#include<queue>using namespace std;#define LL intconst int MAX=1000000000;int n,A,B;int mat[200][200];struct node{LL x,d;node(LL a,LL b){ x=a,d=b;}bool operator <(const node &a) const {if(d==a.d) return x>a.x;return a.d<d;}}; vector<node>p[200]; void init(){   for(int i=0;i<200;i++)p[i].clear();for(int i=0;i<=n;i++){for(int j=0;j<=n;j++){if(i==j) mat[i][j]=0;  //自身点初始化为0 else mat[i][j]=MAX;}}}int floyd(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){for(int k=1;k<=n;k++){mat[j][k]=min(mat[j][k],mat[j][i]+mat[i][k]);    //以最外成作为松弛点 }}}if(mat[A][B]>=MAX) return -1;else return mat[A][B];}int Dijkstra(){int dis[200];for(int i=0;i<=n;i++) dis[i]=MAX;dis[A]=0;priority_queue<node>q;q.push(node(A,dis[A]));while(!q.empty()){node x=q.top();q.pop();for(int i=0;i<p[x.x].size();i++){node y=p[x.x][i];if(dis[y.x]>x.d+y.d){dis[y.x]=x.d+y.d;q.push(node(y.x,dis[y.x]));}}}//for(int i=0;i<=n;i++) printf("%d  ",dis[i]);if(dis[B]==MAX) return -1;else return dis[B];}int main(){while(scanf("%d%d%d",&n,&A,&B)!=EOF){init();for(int i=1;i<=n;i++){int num;scanf("%d",&num);for(int j=1;j<=num;j++){int end;scanf("%d",&end);if(j==1){p[i].push_back(node(end,0));//p[end].push_back(node(i,0));mat[i][end]=0;}else{ p[i].push_back(node(end,1));// p[end].push_back(node(i,1)); mat[i][end]=1;}}}int sum=0;//sum=floyd();sum=Dijkstra();printf("%d\n",sum);}return 0;}