您的位置:首页 > 其它

Codevs 1020 孪生蜘蛛

2017-07-09 08:15 225 查看
题目描述 Description

在G城保卫战中,超级孪生蜘蛛Phantom001和Phantom002作为第三层防卫被派往守护内城南端一带极为隐秘的通道。
根据防护中心的消息,敌方已经有一只特种飞蛾避过第二层防卫,直逼内城南端通道入口。但优秀的蜘蛛已经在每个通道内埋下了坚固的大网,无论飞蛾进入哪个通道,他只有死路一条!(因为他是无法挣脱超级蛛网的)
现在,001和002分别驻扎在某两个通道内。各通道通过内线相通,通过每条内线需要一定的时间。当特种飞蛾被困某处,001或002会迅速赶来把它结果掉(当然是耗时最少的那个)。
001跟002都想尽早的完成任务,他们希望选择在最坏情况下能尽早完成任务的方案。 

输入描述 Input Description

第一行为一个整数N (N<=100) 表示通道数目。
接下来若干行每行三个正整数a,b,t 表示通道a,b有内线相连,通过的时间为t。(t<=100)
(输入保证每个通道都直接/间接连通)

输出描述 Output Description

两个不同的整数x1,x2,分别为001,002驻扎的地点。(如果有多解,请输出x1最小的方案,x1相同则输出x2最小的方案)

这道题由于题目N仅为100,所以可以采用枚举001的位置,再枚举002的位置,最后枚举飞蛾可能出现的位置,n的三次方的复杂度稳稳AC。

接着可以考虑枚举的思路,由于本题会从耗时最小的路赶来,而飞蛾出现位置不一定,所以可以先做一遍floyd求出最短路,然后枚举飞蛾位置,求出每种情况下的最坏情况,即最短路的最大值。其中,最大值中最小的那一种情况,即是题目所求的驻扎地点。

下附C++ 代码

#include<iostream>
#define maxn 105
using namespace std;
int dis[maxn][maxn];
int n;
void init()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
dis[i][j]=990999999;
}
for(int i=1;i<=n;i++)
dis[i][i]=0;
int a,b,c;
while(cin>>a>>b>>c)
{
dis[a][b]=c;
dis[b][a]=c;
}
}
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&j!=k&&k!=i)
{
dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
}
}
int ans1,ans2;
int ans=10000007;
int main()
{
init();
floyd();
for(int p1=1;p1<=n;p1++)
for(int p2=1;p2<=n;p2++)
{
int cal1,cal2,calmax=0;
for(int sp=1;sp<=n;sp++)
{
cal1=dis[p1][sp];
cal2=dis[p2][sp];
calmax=max(min(cal1,cal2),calmax);
}
if(calmax==ans)
{
if(ans1==p1)
{
ans2=min(ans2,p2);
}
else
ans1=min(ans1,p1);
}
else if(calmax<ans)
{
ans=calmax;
ans1=p1;
ans2=p2;
}
}
cout<<ans1<<" "<<ans2<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: