题目
一个有向图,每个点有个默认方向和若干个其他方向,走默认方向权值为0,其他方向权值为1,求最短路
输入
3 2 1(3个点,点2到点1)
2 2 3(2个点,起点为1,2为默认点,3为其他点)
2 3 1(2个点,起点为2,3为默认点,1为其他点)
2 1 2
输出
0
解题思路
其实就像我题目说的那样默认方向权值为0,其他方向权值为1,求最短路。这里用SPFA算法。
代码
#include<cstdio>
using namespace std;
struct woc{int next,x,y,w;
};//日常邻接表
woc a[50001];
int xx,yy,n,m,k,state[10001],ls[10001],t,head,tail,f[10001],star,over;
bool v[10001];
int main()
{scanf("%d%d%d",&n,&star,&over);state[1]=1;int u=0; for (int i=1;i<=n;i++){scanf("%d",&xx);for (int j=1;j<=xx;j++){scanf("%d",&yy);if (j==1) a[++u].w=0;else a[++u].w=1;//判断默认方向a[u].next=ls[i];ls[i]=u;a[u].x=i;a[u].y=yy;//邻接表}} for (int i=1;i<=n;i++) f[i]=2147483647;head=0;tail=1;state[1]=star;v[state[1]]=true;f[star]=0;//初始化while (head!=tail){head++;//出队head=(head-1)%n+1;//循环队列t=ls[state[head]];//读边while (t!=0){if (f[a[t].x]+a[t].w<f[a[t].y]){f[a[t].y]=f[a[t].x]+a[t].w;//松弛if (!v[a[t].y]){tail++;//入队tail=(tail-1)%n+1;//循环队列state[tail]=a[t].y;v[a[t].y]=true;//标记}}t=a[t].next;//读下一条边}v[state[head]]=false;//解封}if (f[over]==2147483647) printf("-1");//如果无解else printf("%d\n",f[over]);
}