• UOJ #32. 【UR #2】跳蚤公路【Floydbellman-ford】


    首先看这个范围很夸张但是其实有限制的也就在1e18*n范围里(走完一圈的边权),然后限制一定是有负环
    用Floyd传递闭包,然后设f[i][j][k]为从1走了i步到j并且有k个x的最短路,用B-F处理,然后有负环就是kx+f[n][i][k]<jx+f[n-1][i][j]
    对每个点求出x的限制
    如果1到v的路径上有负环就不合法,所以用传递闭包出来的连通性把对当前v有限制的区间放到一起,求补集即可
    判-1就是如果最后剩下的个数比1e18/100大就说明有一边是没限制的

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=105;
    const long long inf=1e18;
    int n,m;
    long long f[N][N][N<<1];
    bool a[N][N];
    vector<pair<long long,long long> >b[N],s;
    struct qwe
    {
    	int u,v,w,s;
    }e[N*N];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void minn(long long &x,long long y)
    {
    	if(x>y)
    		x=y;
    }
    void maxx(long long &x,long long y)
    {
    	if(x<y)
    		x=y;
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    		a[i][i]=1;
    	for(int i=1;i<=m;i++)
    	{
    		e[i].u=read(),e[i].v=read(),e[i].w=read(),e[i].s=read();
    		a[e[i].u][e[i].v]=1;
    	}
    	for(int k=1;k<=n;k++)
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++)
    				if(a[i][k]&&a[k][j])
    					a[i][j]=1;
    	memset(f,0x3f,sizeof(f));
    	// inf=f[0][0][0];
    	f[0][1][n]=0;
    	for(int i=1;i<=n;i++)
    		for(int k=0;k<=2*n;k++)
    		{
    			for(int j=1;j<=n;j++)
    				f[i][j][k]=f[i-1][j][k];
    			for(int j=1;j<=m;j++)
    				if(k-e[j].s>=0&&k-e[j].s<=2*n)
    					minn(f[i][e[j].v][k],f[i-1][e[j].u][k-e[j].s]+e[j].w);
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=0;j<=2*n;j++)
    			if(f[n][i][j]<inf)
    			{
    				long long l=-inf,r=inf;
    				for(int k=0;k<=2*n;k++)
    					if(f[n-1][i][k]<inf)
    					{
    						if(j==k)
    						{
    							if(f[n-1][i][j]==f[n][i][j])
    								r=-inf,l=inf;
    						}
    						else if(j<k)
    							maxx(l,floor((double)(f[n-1][i][k]-f[n][i][j])/(double)(j-k))+1);
    						else
    							minn(r,ceil((double)(f[n-1][i][k]-f[n][i][j])/(double)(j-k))-1);
    					}
    					if(l<=r)
    						b[i].push_back(make_pair(l,r));
    			}
    	for(int i=1;i<=n;i++)
    	{
    		s.clear();
    		for(int j=1;j<=n;j++)
    			if(a[j][i])
    				for(int k=0,len=b[j].size();k<len;k++)
    					s.push_back(b[j][k]);
    		sort(s.begin(),s.end());
    		long long l=-inf,r=-inf-1,sm=2*inf+1;
    		for(int j=0,len=s.size();j<len;j++)
    		{
    			if(s[j].first<=r)
    				maxx(r,s[j].second);
    			else
    				sm-=r-l+1,l=s[j].first,r=s[j].second;
    		}
    		sm-=r-l+1;
    		if(sm>=inf/100)
    			puts("-1");
    		else
    			printf("%lld
    ",sm);
    	}
    	return 0;
    }
    
  • 相关阅读:
    CentOS 6.3用ssh无密码登陆其它主机
    堆排序算法以及JAVA实现
    TaskTracker发送Heartbeat以及接受HeartbeatResponse
    Linux常用命令总结
    用eclipse将mapreduce程序打成jar包并在命令行执行
    jquery自定义验证方法
    solaris中几个网络经典命令小结
    DWR的简单总结[转]
    java 编码问题 及转换
    DWR学习详解【转】
  • 原文地址:https://www.cnblogs.com/lokiii/p/11025336.html
Copyright © 2020-2023  润新知