/*****
题目大意:存在N个叉点,算从A点到B点开动开关最多多少次
接下来N行就是输入一个数字num代表与相邻的点的个数,接下来的num个数表示
与i相邻的点的位置;
其实就是把到达该节点的权值自己赋值为0/1;
知道了题意就很简单了;
思路就是SPFA求解最短路,随手写了一个前向星建图栈板SPFA,感觉美滋滋;
****/
#include<cstdio>
#include<stack>
using namespace std;
const int maxn=1e6+7;
const int inf=0x3f3f3f3f;
bool vis[maxn];
int head[maxn],dis[maxn];
int N,A,B,pos=0;
struct node
{
int to,w,next;
}eage[maxn];
void Add(int u,int v,int w)
{
eage[pos].to=v;
eage[pos].w=w;
eage[pos].next=head[u];
head[u]=pos++;
}
void SPFA(int beg,int ed)
{
for(int i=1;i<=N;i++)
{
dis[i]=inf;
vis[i]=0;
}
dis[beg]=0;
vis[beg]=1;
stack<int>Q;
Q.push(beg);
while(!Q.empty())
{
int u=Q.top();
Q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=eage[i].next)
{
int v=eage[i].to;
if(dis[v]>dis[u]+eage[i].w)
{
dis[v]=dis[u]+eage[i].w;
if(!vis[v]) {vis[v]=1;Q.push(v);}
}
}
}
}
int main ()
{
scanf("%d %d %d",&N,&A,&B);
for(int i=1;i<=N;i++)
head[i]=-1;
for(int i=1;i<=N;i++)
{
int k;
scanf("%d",&k);
for(int j=1;j<=k;j++)
{
int b;
scanf("%d",&b);
/***
开始连接的点的不需要打开什么的,本身就在那个位置
简单的说就是已经指定了方向,所以开始的权值为0;
***/
if(j==1) Add(i,b,0);
else Add(i,b,1);
}
}
SPFA(A,B);
if(dis[B]<inf) printf("%d\n",dis[B]);
else printf("-1\n");
return 0;
}
POJ - 1847 Tram(火车转换接口,权值0/1化) 栈版SPFA
最新推荐文章于 2019-08-25 17:54:03 发布