题目大意:有n个交叉点,就当做有n个点就行,然后这些点和其他点有些路径,每个点是一个开关,开关只能有一个方向走一条路,而第一个数就是默认的开关指向,不用旋转。标记为0,其他的标记为1
3 2 1 //有3个开关点,计算从第二个到第一个最少需要旋转几次 若找不到输出-1
2 2 3//第1个开关可以通向2 和3 ,通向2不需要旋转,通向3需要旋转1次
2 3 1//第2个开关可以通向3 和1, 通向3不需要旋转,通向1需要旋转1次
解题思路:直接建图,最短路即可,floyd dijstra bellman spfa这四种算法都可以 就一模板题而已
下面给出floyd dijdtra spfa 三种做法的AC代码
dijdtra算法
//Memory: 176 KB
//Time: 0 MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x)
#define dsc(x,y) scanf("%d%d",&x,&y)
#define sssc(x) scanf("%s",s)
#define sdsc(x,y) scanf("%s %s",x,y)
#define ssc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define pr(x) printf("%d\n",x)
#define FOR(i,n,o) for(int i=o;i<=n;i++)
#define lcr(a,b) memset(a,b,sizeof(a))
#define Inf 1<<29
const int maxn=105;
int n,c,z,mp[maxn][maxn],dis[maxn],vis[maxn];
void dij(int s)
{
FOR(i,n,1)
{
vis[i]=0;
dis[i]=mp[s][i];
}
vis[s]=1;
dis[s]=0;
FOR(i,n,1)
{
int to;
int minn=Inf;
FOR(j,n,1)
{
if(!vis[j]&&dis[j]<minn)
{
to=j;
minn=dis[j];
}
}
if(minn==Inf)
{
break;
}
vis[to]=1;
FOR(j,n,1)
{
if(!vis[j])
dis[j]=min(dis[j],dis[to]+mp[to][j]);
}
}
}
int main()
{
while(~ssc(n,c,z))
{
FOR(i,n,1)
{
FOR(j,n,1)
{
if(i!=j)
mp[i][j]=Inf;
else
mp[i][j]=0;
}
}
int t,a;
FOR(i,n,1)
{
sc(t);
FOR(j,t-1,0)
{
sc(a);
if(j==0)
mp[i][a]=0;
else
mp[i][a]=1;
}
}
dij(c);
if(dis[z]==Inf)
puts("-1");
else
pr(dis[z]);
}
return 0;
}
floyd算法
//Memory: 176 KB
//Time: 0 MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x)
#define dsc(x,y) scanf("%d%d",&x,&y)
#define sssc(x) scanf("%s",s)
#define sdsc(x,y) scanf("%s %s",x,y)
#define ssc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define pr(x) printf("%d\n",x)
#define FOR(i,n,o) for(int i=o;i<=n;i++)
#define lcr(a,b) memset(a,b,sizeof(a))
#define Inf 1<<29
const int maxn=105;
int n,c,z,mp[maxn][maxn];
int main()
{
while(~ssc(n,c,z))
{
FOR(i,n,1)
{
FOR(j,n,1)
{
if(i!=j)
mp[i][j]=Inf;
else
mp[i][j]=0;
}
}
int t,a;
FOR(i,n,1)
{
sc(t);
FOR(j,t-1,0)
{
sc(a);
if(j==0)
mp[i][a]=0;
else
mp[i][a]=1;
}
}
FOR(k,n,1)
{
FOR(i,n,1)
{
FOR(j,n,1)
{
if(i!=j&&j!=k)
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
}
if(mp[c][z]==Inf)
puts("-1");
else
pr(mp[c][z]);
}
return 0;
}
spfa算法
//Memory: 160 KB
//Time: 0 MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x)
#define dsc(x,y) scanf("%d%d",&x,&y)
#define sssc(x) scanf("%s",s)
#define sdsc(x,y) scanf("%s %s",x,y)
#define ssc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define pr(x) printf("%d\n",x)
#define FOR(i,n,o) for(int i=o;i<=n;i++)
#define lcr(a,b) memset(a,b,sizeof(a))
#define Inf 1<<29
const int maxn=105;
int n,c,z,dis[maxn],head[maxn],e,cnt[maxn],vis[maxn];
struct node
{
int u;
int v;
int w;
int next;
}q[maxn*maxn];
void add(int u,int v,int w)
{
q[e].u=u;
q[e].v=v;
q[e].w=w;
q[e].next=head[u];
head[u]=e++;
}
queue <int> que;
void SPFA(int s)
{
while(!que.empty())
que.pop();
FOR(i,n,1)
{
dis[i]=Inf;
vis[i]=0;
cnt[i]=0;
}
dis[s]=0;
vis[s]=1;
que.push(s);
while(!que.empty())
{
int temp=que.front();
que.pop();
vis[temp]=0;
for(int i=head[temp];i!=-1;i=q[i].next)
{
int v=q[i].v;
if(dis[v]>dis[temp]+q[i].w)
{
dis[v]=dis[temp]+q[i].w;
if(!vis[v])
{
vis[v]=1;
que.push(v);
}
}
}
}
}
int main()
{
while(~ssc(n,c,z))
{
e=0;
lcr(head,-1);
int t,a;
FOR(i,n,1)
{
sc(t);
FOR(j,t-1,0)
{
sc(a);
if(j==0)
add(i,a,0);
else
add(i,a,1);
}
}
SPFA(c);
if(dis[z]==Inf)
puts("-1");
else
pr(dis[z]);
}
return 0;
}
END!!!!!!!!!!!!!!!!!!!!!