• codeforce D. Shortest Cycle(floyd求最短环)


    题目链接:http://codeforces.com/contest/1206/problem/D

    给n个点,如果点a[ i ] &a[ j ] 不为0,则点a[ i ] 和 a[ j ] 直接可以连接双向边,如果这些点形成的图中有环,求最短路径的环,如果没有输出-1.

    思路:整体是用floyd求最短环,但是数据量很大,有1e5的数据,空跑floyd直接超时,但是由于题目的特殊性,两数相与不为0才有边,那么任意的a[ i ]二进制是有63位的,那么一个数字的二进制最多有63个1,如果总体数字的二进制63位中的任意一位存在三个以上的1,说明有三个数相与都是不为0的,三个数可以互相连边,那么最短环一定是3,靠这个结论解答可以大大缩短时间复杂度,如果a[ i ](不为0)个数多到某一个Max值时,则某一位上1的个数一定会超过3,那么这个Max值具体是多少呢?没有详细计算,但是一定不会超过63 * 2 = 126个,因为就算每一位分配2个“1”,第127个必定使得一位有3个“1”,那么可以将Max可以暂定为126,也就是说1e5的计算数据大大减少到了126,这样跑floyd就不会超时了。注意如果a[ i ] = 0,直接可以不会加入cnt计数中,因为0与任意数相与都是0.

    AC代码:

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cstring>
    #define maxn 100005
    #define inf 0x3f3f3f3f
    using namespace std;
    long long int a[maxn];
    long long int dist[200][200];
    long long int g[200][200];
    int n;
    int cnt = 1;
    long long int ans = 0x3f3f3f3f;
    void floyd(){
    	for(long long int k = 1;k<=cnt;k++){
    		for(long long int i = 1;i<k;i++){
    			for(long long int j = i+1;j<k;j++){
    				if(dist[i][j] == inf || g[j][k] == inf || g[i][k] == inf){
    					continue;
    				}
    				ans = min(ans,dist[i][j]+g[j][k]+g[k][i]);
    			}
    		}
    		
    		for(long long int i = 1;i<=cnt;i++){
    			for(long long int j = 1;j<=cnt;j++){
    				dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
    			}
    		}
    	}
    }
    int main(){
    	cin>>n;
    	for(long long int i = 1;i<=n;i++){
    		long long int t;
    		cin>>t;
    		if(t){
    			a[cnt] = t;
    			cnt++;
    		}
    	}
    	if(cnt > 126){
    		cout<<3;
    		return 0;
    	}
    	for(long long int i = 1;i<=cnt;i++){
    		for(long long int j = i+1;j<=cnt;j++){
    			if((a[i] & a[j]) ){
    				dist[i][j] = 1,dist[j][i] = 1;
    				g[i][j] = 1,g[j][i] = 1;
    			}
    			else{
    				dist[i][j] = inf,dist[j][i] = inf;
    				g[i][j] = inf,g[j][i] = inf;
    			}
    		}
    	}
    	floyd();
    	if(ans == inf ){
    		cout<<-1;
    		return 0;
    	}
    	cout<<ans;
    	return 0;
    }
  • 相关阅读:
    短连接生成
    google 定位 标记 地址解码 逆解码
    Laravel 文件上传
    Laravel
    对接航信开票-在线二维码开票
    win 下 composer 安装
    对接美团外卖开放平台
    IOS 弹框在微信中导致输入框等失焦 偏移问题解决
    微信公众号-高德地图实例
    对接百度地图API 实现地址转经纬度
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12129636.html
Copyright © 2020-2023  润新知