题目大意:哎,本题读题就读了三遍才搞懂输入的究竟是什么东西,其实只要理解input和output就行了
input是这样的,第一行输出经济人的个数,并且编号为1....n, 接下来n行每行第一个数为与n联系的人的个数m,接下来有m对,没对第一个表示与n联系的人的编号,第二个数表示两人取得联系的时间,t
output是这样的,输出从哪个人发出信息取得的总时间最短,并求出这个从该人向其他人发出信息最长时间
解决:floyd算法求出各个点到其他点的最短时间,,并查集判断是否是连通的 ,代码比较简单就不加注释了
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N= 105;
const int MAX=0xf3f3f3f;
int num[N];
bool mark[N];
int cost[N][N];
int mx[N];
int n;
void initNum()
{
memset(num,-1,sizeof(num));
memset(mark,0,sizeof(mark));
}
void init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j)cost[i][j]=0;
else cost[i][j]=MAX;
}
int find(int x)
{
if(num[x]<0)return x;
else return num[x]=find(num[x]);
}
void merge(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa==fb)return ;
int t=num[fa]+num[fb];
if(num[fa]>num[fb]){num[fa]=fb;num[fb]=t;}
else {num[fb]=fa;num[fa]=t;}
}
void floyd()
{
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(cost[i][k] + cost[k][j] < cost[i][j])
cost[i][j]=cost[i][k]+cost[k][j];
int min=0x7fffffff,sum,pos=-1;
memset(mx,-1,sizeof(mx));
for(i=1;i<=n;i++)
{
sum=0;
for(j=1;j<=n;j++)
{
sum+=cost[i][j];
if(cost[i][j]!=MAX && cost[i][j]>mx[i])mx[i]=cost[i][j];
}
if(sum<min){min=sum;pos=i;}
}
printf("%d %d\n",pos,mx[pos]);
}
int main()
{
while( scanf("%d",&n),n)
{
init();
initNum();
int i,m,adj,w;
for(i=1;i<=n;i++)
{
mark[i]=1;
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&adj,&w);
if(i!=adj){merge(i,adj);mark[adj]=1;}
cost[i][adj]=w;
}
}
int cnt=0;
for(i=1;i<=n && cnt!=2;i++)
if(mark[i] && num[i]<0)cnt++;
if(cnt==2)printf("disjoint\n");
else
floyd();
}
system("pause");
return 0;
}