• USACO cowtour Floyd + 枚举


    给出来的数据量还是能够的。题意:有若干个牧场,至少有两个不连通,一个牧场的直径就是牧场中最远的两个牧区的距离。要求找出几个牧场中最短的直径,就是找一条路径连接几个牧区。使这个直径终于最小。

    基本方法。把整个图依据输入划分成几个不连通的牧区,然后求出每一个牧区的直径(即每一个连通块中的最长路径),然后枚举两个不在同一牧区的点,设blocks[i]记录第i个节点所在连通块的直径。那么result = min(blocks[i] + dis(i, j) + blocks[j]),能够用并查级推断两个点是否连通


    /*
    ID:kevin_s1
    PROG:cowtour
    LANG:C++
    */
    
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <vector>
    #include <map>
    #include <set>
    #include <algorithm>
    #include <cstdlib>
    #include <list>
    #include <cmath>
    
    using namespace std;
    
    #define MAXN 175
    const double INF = 1E15;
    
    //gobal variable====
    int N;
    
    struct point{
    	double x;
    	double y;
    }points[MAXN];
    
    double Graph[MAXN][MAXN];
    
    double result;
    
    int Father[MAXN];
    int Rank[MAXN];
    
    double blocks[MAXN];
    //==================
    
    
    //function==========
    
    int Find(int x){
    	while(x != Father[x]){
    		x = Father[x];
    	}
    	return x;
    }
    
    bool check(int x, int y){
    	x = Find(x);
    	y = Find(y);
    	if(x == y)
    		return true;
    	else
    		return false;
    }
    
    void Union(int x, int y){
    	x = Find(x);
    	y = Find(y);
    	if(x == y)
    		return;
    	if(Rank[x] >= Rank[y]){
    		Father[y] = x;
    		Rank[x] += Rank[y];
    	}
    	else{
    		Father[x] = y;
    		Rank[y] += Rank[x];
    	}
    }
    
    double dist(point start, point end){
    	return sqrt((end.x - start.x)*(end.x - start.x) + (end.y - start.y)*(end.y - start.y));
    }
    
    void Input(){
    	cin>>N;
    	for(int i = 1; i <= N; i++){
    		cin>>points[i].x>>points[i].y;
    		blocks[i] = -1;
    		Father[i] = i;
    		Rank[i] = 1;
    	}
    	char flg;
    	for(int i = 1; i <= N; i++)
    		for(int j = 1; j <= N; j++){
    			cin>>flg;
    			if(i == j)
    				Graph[i][j] = 0;
    			else if(flg == '1'){
    				Union(i, j);
    				Graph[i][j] = dist(points[i], points[j]);
    			}
    			else if(flg == '0')
    				Graph[i][j] = INF;
    		}
    }
    
    void Floyd(){
    	for(int k = 1; k <= N; k++){
    		for(int i = 1; i <= N; i++){
    			for(int j = 1; j <= N; j++){
    				if(k == i || k == j)
    					continue;
    				if(Graph[i][j] > Graph[i][k] + Graph[k][j]){
    					Graph[i][j] = Graph[i][k] + Graph[k][j];
    				}
    			}
    		}
    	}
    }
    
    void print(){
    	for(int i = 1; i <= N; i++){
    		for(int j = 1; j <= N; j++){
    			cout<<Graph[i][j]<<" ";
    		}
    		cout<<endl;
    	}
    }
    
    
    //==================
    
    int main(){
    	freopen("cowtour.in","r",stdin);
    	freopen("cowtour.out","w",stdout);
    	Input();
    	Floyd();
    	for(int i = 1; i <= N; i++){
    		for(int j = 1; j <= N; j++){
    			if(Graph[i][j] != INF && blocks[i] < Graph[j][i])
    				blocks[i] = Graph[j][i];
    		}
    	}
    	
    	result = INF;
    	for(int i = 1; i <= N; i++){
    		for(int j = i + 1; j <= N; j++){
    			if(Graph[i][j] == INF && !check(i, j)){
    				double dis = dist(points[i], points[j]);
    				if(blocks[i] + dis + blocks[j] < result)
    					result = blocks[i] + dis + blocks[j];
    			}
    		}
    	}
    
    	for(int i = 1; i <= N; i++)
    		if(blocks[i] > result)
    			result = blocks[i];
    
    	printf("%.6lf
    ", result);
    	return 0;
    }
    


  • 相关阅读:
    Spring事务原理一探
    浅谈AI视频技术超分辨率
    网易云信独家技术支持,壹点灵领跑心理服务行业
    音视频技术“塔尖”之争,网易云信如何C位出道?
    浅析为何使用融合CDN是大趋势?
    谈谈接入各种第三方推送平台的技术方案和一点经验
    编解码器之战:AV1、HEVC、VP9和VVC
    三年深入探索,网易云信让在线医疗做到技术“在线”
    5分钟学会Java9-Java11的七大新特性
    网易云信案例简析:锤科情怀缩影,子弹短信路在何方?
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6940193.html
Copyright © 2020-2023  润新知