USACO 2.4 Cow Tours


这题综合了dfs,floyd算法。

首先用 floyd计算出两两之间的最短路径。然后用dfs将图着色。对每两两不同颜色的结点,我们把它们相连,然后看产生的图的直径的大小。
直径的大小只可能仍为原两连通图直径之一,或者是包括新添加的路径所产生的最长路径,取这三者中的最大值。新路径产生的最长路径只可能是两点的距离加上两点到其他点的最长距离。最开始的时候只考虑了新添加的路径,没考虑原直径会比新路径大的情况,wa了n次。。

#include <iostream>
#include 
<fstream>

#include 
<cfloat>
#include 
<cmath>

using namespace std;

ifstream fin(
"cowtour.in");
ofstream fout(
"cowtour.out");

#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif

double path[150][150];

char graph[150][150];

int x[150];
int y[150];

int n;

int color[150];

double diameter[150];
double maxPath[150];

void floyd()
{
    
for(int k=0;k<n;++k)
        
for(int i=0;i<n;++i)
            
for(int j=0;j<n;++j){
                
if(i!=j){
                    path[i][j]
=min(path[i][j],path[i][k]+path[k][j]);
                }
            }
}

void make_color(int i,int c)
{
    
if( color[i]!=0 )
        
return;

    color[i] 
= c;

    
for(int j=0;j<n;++j){
        
if(color[j]==0&&graph[i][j])
            make_color(j,c);
    }
}


void solve()
{
    
in>>n;

    
for(int i=0;i<n;++i){
        
in>>x[i]>>y[i];
    }

    
for(int i=0;i<n;++i){
        
string s;
        
in>>s;
        
for(int j=0;j<n;++j){
            graph[i][j]
=s[j]-'0';
            
if(graph[i][j]){
                path[i][j] 
= sqrt( (x[i]-x[j])*(x[i]-x[j])
                    
+(y[i]-y[j])*(y[i]-y[j]) );
            }
else{
                path[i][j] 
= DBL_MAX/4;
            }
        }
    }

    floyd();

    
int c = 0;
    
for(int i=0;i<n;++i)
        
if(color[i]==0)
            make_color(i,
++c);


    
for(int i=0;i<n;++i){
        maxPath[i] 
= 0;
        
for(int j=0;j<n;++j){
            
if(i!=j&&color[i]==color[j]){
                maxPath[i] 
= max(maxPath[i],path[i][j]);
            }
        }

        diameter[color[i]] 
= max(diameter[color[i]],maxPath[i]);
    }


    
double dia = DBL_MAX;

    
for(int i=0;i<n;++i)
        
for(int j=i+1;j<n;++j){

            
if(color[i]==color[j]) continue;

            
double d1 = 0;
            
for(int p=0;p<n;++p){
                
if(i!=p&&color[i]==color[p])
                    d1 
= max(d1,path[i][p]);
            }

            
double d2 = 0;
            
for(int p=0;p<n;++p){
                
if(j!=p&&color[j]==color[p])
                    d2 
= max(d2,path[j][p]);
            }

            
double dist = sqrt( (x[i]-x[j])*(x[i]-x[j])+
                    (y[i]
-y[j])*(y[i]-y[j]) );

            dia 
= min(dia,max(d1+d2+dist,max(diameter[color[i]],diameter[color[j]])) );
        }

    
out.setf(ios::fixed,ios::floatfield);
    
out.precision(6);
    
out<<dia<<endl;
}

int main(int argc,char *argv[])
{
    solve(); 
    
return 0;
}


posted on 2009-06-27 22:10 YZY 阅读(1517) 评论(0)  编辑 收藏 引用 所属分类: AlgorithmUSACO搜索图论


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜