POJ 1847 Tram

这里写图片描述

题目大意:有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!!!!!!!!!!!!!!!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值