题目的背景很有意思,比赛的时候死活过不了,今天提交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:58 | C++ | 910 | 15696 |
majia5 |