题目大意:哎,本题读题就读了三遍才搞懂输入的究竟是什么东西,其实只要理解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; }