又是一道违法犯罪的题
背景:我要造谣,但不自己传谣,而是把这个任务发给n个人中的一个。这n个人每个人都有自己的情报网,具体来说就是每个人可以联系到m个人,并给出联系到的人编号t和联系时间w。问我把任务发给谁完成速度最快,输出这个人的编号和最短时间。
题意:一张带权图,求以哪个点位起点遍历完整张图权值和最小。如不联通输出disjoint。
解:因为n的数量很小,直接跑Floyd求每两个点间最短路。然后遍历每个点,求到达每个点距离最大值,注意跳过自己,和要跑满n-1个点才能更新答案。Floyd初始化为最大值时最大值不能设得太大,不然会炸int。
代码:
1 #include<stdio.h> 2 #include <algorithm> 3 #include <queue> 4 #include <math.h> 5 using namespace std; 6 #define ll long long 7 #define maxx 205 8 #define inf 1e9 9 //#define int long long 10 struct edge{ 11 int u,v,w; 12 int nxt; 13 }e[maxx*2]; 14 int head[maxx]={0},cnt=0; 15 void add(int u,int v,int w){ 16 e[++cnt].u=u; 17 e[cnt].v=v; 18 e[cnt].w=w; 19 e[cnt].nxt=head[u]; 20 head[u]=cnt; 21 } 22 int n; 23 int mp[maxx][maxx]; 24 signed main() { 25 while(~scanf("%d",&n)){ 26 if(n==0) 27 break; 28 for(int i=1;i<=n;i++) { 29 for (int j = 1; j <= n; j++) 30 mp[i][j] = inf; 31 } 32 for(int i=1;i<=n;i++){ 33 int m; 34 scanf("%d",&m); 35 for(int j=0;j<m;j++){ 36 int t,w; 37 scanf("%d%d",&t,&w); 38 mp[i][t]=w; 39 } 40 } 41 for(int k=1;k<=n;k++) 42 for(int i=1;i<=n;i++) 43 for(int j=1;j<=n;j++) 44 mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]); 45 int ans=inf,per=0; 46 for(int i=1;i<=n;i++) { 47 int temp=0,cnt1=0; 48 for (int j = 1; j <= n; j++){ 49 if(i==j) 50 continue; 51 if(mp[i][j]==inf) 52 continue; 53 temp=max(temp,mp[i][j]); 54 cnt1++; 55 } 56 if(temp<ans&&cnt1==n-1) 57 ans=temp,per=i; 58 } 59 if(ans!=inf) 60 printf("%d %d\n",per,ans); 61 else 62 printf("disjoint\n"); 63 } 64 return 0; 65 }
滚去写数据结构作业了qaqqqqqqqq