POJ1125求股票经纪人传递消息用的最短时间,以及对应的消息散布的起点。
问题的本质就是求最短路径,对于每一个可能的散布消息的起点,我们计算该点到所有其他点最短路径的最大值,即为从该点开始散布消息所需要的时间,然后,计算每个可能的起点,从中找到每个起点对应所需时间的最小值,即是最短的传播时间,对应的起点,即是散布消息的起点。
本来我用dijkstra算法,代码如下
#include<iostream>
#include<algorithm>
#define MAX 101
int in[MAX][MAX];
int shortestRoute[MAX];
int n;
using namespace std;
void dijkstra(int st){
for(int i=1;i<=n;i++){
shortestRoute[i]=10000;
}
shortestRoute[st]=0;
bool mark[MAX];
for(int i=1;i<=n;i++)
mark[i]=false;
mark[st]=true;
int flag=0;
for(int i=1;i<=n;i++){
if(mark[i]==false){
flag=1;
break;
}
}
while(flag){
int minn=100000;
int nextRec;
for(int i=1;i<=n;i++){
if(mark[i]==false){
for(int j=1;j<=n;j++){
if(in[j][i]<=10)
shortestRoute[i]=min(shortestRoute[i],shortestRoute[j]+in[j][i]);
}
if(shortestRoute[i]<minn){
minn=shortestRoute[i];
nextRec=i;
}
}
}
mark[nextRec]=true;
flag=0;
for(int i=1;i<=n;i++){
if(mark[i]==false){
flag=1;
break;
}
}
}
}
int main(){
cin>>n;
while(n!=0){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j){
in[i][j]=0;
continue;
}
in[i][j]=11;
}
int num;
int target;
int time;
int count=1;
while(count<=n){
cin>>num;
while(num--){
cin>>target;
cin>>time;
in[count][target]=time;
}
count++;
}
int mx[MAX];
for(int i=1;i<=n;i++){
dijkstra(i);
mx[i]=0;
for(int j=1;j<=n;j++){
if(shortestRoute[j]>mx[i])
mx[i]=shortestRoute[j];
}
}
int mi=10000;
int rc=0;
for(int i=1;i<=n;i++){
if(mx[i]<mi){
mi=mx[i];
rc=i;
}
}
if(mi!=10000)
cout<<rc<<' '<<mi<<endl;
else
cout<<"disjoint"<<endl;
cin>>n;
}
}
上传后时间是16MS,后来才知道,因为本题要计算两两之间的最短路径,所以更好的选择是Floyd算法,
从而代码改变如下
#include<iostream>
#include <cstring>
#define MAX 101
int shortestRoute[MAX][MAX];
int n;
using namespace std;
void myFloyd(){
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
if(shortestRoute[i][k]!=10000)
for(int j=1;j<=n;j++){
if(shortestRoute[k][j]!=10000)
if(shortestRoute[i][j]>shortestRoute[i][k]+shortestRoute[k][j]){
shortestRoute[i][j]=shortestRoute[i][k]+shortestRoute[k][j];
}
}
}
int main(){
cin>>n;
while(n!=0){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j){
shortestRoute[i][j]=0;
continue;
}
shortestRoute[i][j]=10000;
}
int num;
int target;
int time;
int count=1;
while(count<=n){
cin>>num;
while(num--){
cin>>target;
cin>>time;
shortestRoute[count][target]=time;
}
count++;
}
myFloyd();
int mx=0;
int rc;
int mn=10000;
for(int i=1;i<=n;i++){
mx=0;
for(int j=1;j<=n;j++){
if(shortestRoute[i][j]>mx){
mx=shortestRoute[i][j];
}
}
if(mx<mn)
{
mn=mx;
rc=i;
}
}
if(mn!=10000)
cout<<rc<<' '<<mn<<endl;
else
cout<<"disjoint"<<endl;
cin>>n;
}
}
这样提交上去就是0MS啦