ZJU 3080 ChiBi

来源:互联网 发布:中国高尔夫网络电视台 编辑:程序博客网 时间:2024/05/21 17:48

题目的背景很有意思,比赛的时候死活过不了,今天提交2次1WA后AC,感觉和USACO上一题类似.主要是floyd的灵活运用.

首先把所给的点划分成若干个连通区域,题目告诉我们这些点集大小不超过100,对于这些点floyd可以知道最多就是o(1000000)~于是枚举每个集合中的每个点,假设d[i]表示士兵到i点所需要的时间,那么点燃这片区域的船所需要的最小的时间:d[i]+max(mat[i][j]).对于每一个集合所得到的最小时间取最大值便是答案.

核心代码:

#define inf 1000000000
int mat[101][101],P[101],Pcnt,grap[1001][1001],d[1001],ans,N;
bool gflag[1001];
void dfs(int x)
{
    int i;
    gflag[x]=true;
    P[Pcnt++]=x;
    for(i=0;i<N;i++)
    {
        if(gflag[i]||grap[i][x]==inf)continue;
        dfs(i);
    }
}
void solve(int x)
{
    int i,j,k,tmp=inf,buf;
    Pcnt=0;
    dfs(x);
    for(i=0;i<Pcnt;i++)for(j=0;j<Pcnt;j++)mat[i][j]=grap[P[i]][P[j]];
    //floyd...
    for(k=0;k<Pcnt;k++)
        for(i=0;i<Pcnt;i++)
            for(j=0;j<Pcnt;j++)
                mat[i][j]=min(mat[i][k]+mat[k][j],mat[i][j]);
    for(i=0;i<Pcnt;i++)
    {
        //select i...
        buf=0;
        for(j=0;j<Pcnt;j++)
        {
            if(i==j)continue;
            if(buf<mat[i][j])
                buf=mat[i][j];
        }
        if(buf+d[P[i]]<tmp)
            tmp=buf+d[P[i]];
    }
    if(tmp>ans)
        ans=tmp;
}

 

 

 

2009-01-26 15:38:58C++91015696

 

majia5

原创粉丝点击