zoukankan      html  css  js  c++  java
  • spfa优化时间复杂度及判负环

    NOI2018 Day1 T1有许多人用spfa被卡掉25分。

    注意:写spfa绝对不用STL,因为出题人会不怀好意的卡掉它。

    我也是愿意写spfa的人.(毕竟简单)。在这里总结一下spfa的优化

    1.普通spfa会开一个数组。可以用循环队列优化.(教程书中都有).

    2.我们在把点加入队列时,随机从队首或队尾加入(几乎没人会卡掉)。

    如果嫌麻烦,可以开成栈。

    3.设要加入的节点是j,队首元素为i,若dist(j) < dist(i),则将j插入队首,否则插入队尾。

    4.设队首元素为i,每次弹出时进行判断,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,则将i出对进行松弛操作。

    这几种方法选一种或两种就够了。

    普通spfa就不说了。

    负环就是在普通spfa上加一句话,若扩展的点已经被扩展n次就说明有负环了。

    题目:VIJOS P1053 Easy sssp

    代码如下:

    #include<cstdio>
    #include<cstring>
    #define N 101000
    int n,m,s;
    int to[N];
    int head[N];
    int nex[N];
    int val[N];
    int f[N];
    int que[N];
    int cnt[N];
    int is[N];
    int inq[N];
    int a,b,c,idx;
    void push(int &x)
    {
    	x++;
    	if(x==N)
    		x=1;
    }
    void addedge(int a,int b,int c)
    {
    	nex[++idx]=head[a];
    	head[a]=idx;
    	to[idx]=b;
    	val[idx]=c;
    }
    bool spfa(int s)
    {
    	for(int i=1;i<=n;i++)
    		inq[i]=0,cnt[i]=0,f[i]=0x3f3f3f3f;
    	f[s]=0;
    	cnt[s]=1;
    	inq[s]=1;
    	int front=0,tail=0;
    	que[tail]=s;
    	push(tail);
    	while(front!=tail)
    	{
    		int idx1=que[front];
    		push(front);
    		inq[idx1]=0;
    		for(int i=head[idx1];i;i=nex[i])
    		{
    			if(f[to[i]]>f[idx1]+val[i])
    			{
    				f[to[i]]=f[idx1]+val[i];
    				if(!inq[to[i]])
    				{
    					inq[to[i]]=1;
    					que[tail]=to[i];
    					push(tail);
    					cnt[to[i]]++;//记录入队次数
    					if(cnt[to[i]]>n)
    						return 0;					
    				}
    			}
    		}
    	}
    	return 1;
    }
    int main()
    {
    	scanf("%d%d%d",&n,&m,&s);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d%d",&a,&b,&c);
    		if(a==b&&c<0)
    		{
    			puts("-1");
    			return 0;
    		}
    		if(a!=b)
    			addedge(a,b,c);
    	}
    	memset(f,0x3f,sizeof(f));
    	memset(que,0,sizeof(que));
    	int maxn=n+1;//建一个空节点,用这个点跑spfa
    	for(int i=1;i<=n;i++)
    		addedge(maxn,i,0);
    	if(!spfa(maxn))
    	{
    		puts("-1");
    		return 0;
    	}
    	spfa(s);
    	for(int i=1;i<=n;i++)
    	{
    		if(f[i]>=0x3f3f3f3f)
    			printf("NoPath\n");
    		else
    			printf("%d\n",f[i]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    应用程序池的配置 狼
    SQL跨数据库复制表数据 狼
    <script language= "javascript " for= "window " event= "onload "> 狼
    禁止虚拟目录继承根目录下web.config中的有些配置 web.config的继承禁止方法 狼
    linux 在程序里修改系统时间
    xlinux下载地址
    安装tslib1.4出现的问题汇总
    linux之看门狗 (转)
    VC中显示GIF图片
    mdev 自动挂载U盘成功
  • 原文地址:https://www.cnblogs.com/342zhuyongqi/p/9801331.html
Copyright © 2011-2022 走看看