zoukankan      html  css  js  c++  java
  • POJ1847 Tram SPFA算法变形

    原题地址:http://poj.org/problem?id=1847

    Tram:有轨电车

    这题就是构造一个有向无权图,然后每一个点都会有一个开关,这个开关指向他的其中一个出度。当途经这个点的时候,如果要从开关指向的边离开,则没事,如果不从开关指向的边离开,那么就要下车把开关掰到要离开的那条边上去。注意,离开之后那个开关是不会“弹”回去的。这跟现实铁路中的道岔还挺像。

    这里我们用邻接表+SPFA来实现。注意是没有边权的。然后加了个switched数组,switched[i]表示第i个点开关指向的边的编号。在松弛代码中,我们会用到这个玩意儿。SPFA算法的队列使用STL的队列(手打队列麻烦)

    注意最后不连通的判断,因为图是没有负权的(因为你最低也就是0,不可能走一圈下来掰了-1次开关吧),所以不用判断点是否入队超N次。不连通说明肯定没有搜到终点,终点的d数组肯定也没有被更新,所以就 判断是否为INF(0x3f3f3f3f)就能判断是否连通。

    代码:

    //Accepted
    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    queue<int>q;
    struct Edge
    {
    	int v,next;
    }a[10010];
    int n,m=0,src,dest,tmp,tmp2,link[1010],d[1010],switched[1010];
    bool visit[1010];
    void addedge(int s,int d)
    {
    	m++;
    	a[m].v=d;
    	a[m].next=link[s];
    	link[s]=m;
    }
    void spfa()
    {
    	q.push(src);
    	d[src]=0;
    	visit[src]=true;
    	while(!q.empty())
    	{
    		int x=q.front();
    		q.pop();
    		visit[x]=0;
    		for(int i=link[x];i!=0;i=a[i].next)
    		{
    			if(d[x]+(switched[x]==a[i].v?0:1)<d[a[i].v])
    			{
    				d[a[i].v]=d[x]+(switched[x]==a[i].v?0:1);
    				if(visit[a[i].v]==false)
    				{
    					visit[a[i].v]=true;
    					q.push(a[i].v);
    				}
    				
    			}
    		}
    	}
    }
    int main()
    {
    	memset(d,0x3f,sizeof(d));
    	scanf("%d%d%d",&n,&src,&dest);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&tmp);
    		for(int j=1;j<=tmp;j++)
    		{
    			scanf("%d",&tmp2);
    			if(j==1)switched[i]=tmp2;
    			addedge(i,tmp2);
    		}
    	}
    	spfa();
    	if(d[dest]==0x3f3f3f3f)printf("-1
    ");
    	else
    	printf("%d
    ",d[dest]);
    	return 0;
    }
    
  • 相关阅读:
    C语言程序设计100例之(12):Eratosthenes筛法求质数
    C语言程序设计100例之(11):求质数
    C语言程序设计100例之(10):最大公约数
    C语言程序设计100例之(9):生理周期
    C语言程序设计100例之(8):尼科彻斯定理
    C语言程序设计100例之(7):级数求和
    C/C++ 内部连接与外部连接
    C/C++ 内存管理问题
    C/C++浮点数的比较
    C/C++规范
  • 原文地址:https://www.cnblogs.com/oier/p/5560711.html
Copyright © 2011-2022 走看看