题目大意:有n个股票经纪人,他们之间互相传递消息,且耗时不同,问从哪个人开始传递消息,最终所有人都收到消息的最短耗时,如果不能让所有人都收到消息,则输出disjoint
输入:(可以有很多case,输入以0结束)
n(1~100)
第i个人的联系人个数 第1个联系人的号码 耗时 第2个联系人的号码 耗时 ...(联系人个数0~n-1 耗时1~10)
0
输出:起始人号码 最短耗时时长(对每一个数据集输出一行答案)
分析:dijstra枚举或者多源最短路floyd或者bellman或者spfa求出每人作为起始点传递消息所需的传播时间,由于可在同一时间传播,所以传播时间一定是源点到每个联系人的最短路径中的最远距离,然后枚举源点,找出所有最远距离中的最小值即可
代码:
方法一:floyd。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int n;
int edges[105][105];
int main() {
while (~scanf("%d", &n) && n) {
memset(edges, 0x3f, sizeof(edges));
int t, a, b;
for (int i = 1; i <= n; i++) {
scanf("%d", &t);
for (int j = 1; j <= t; j++) {
scanf("%d %d", &a, &b);
edges[i][a] = b;
}
edges[i][i] = 0;
}
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
edges[i][j] = min(edges[i][j], edges[i][k] + edges[k][j]);
int ans = 0x3f3f3f3f;
int idx = 0;
for (int i = 1; i <= n; i++) {
int dist = 0;
for (int j = 1; j <= n; j++)
dist = max(dist, edges[i][j]);
if (dist < ans) {
ans = dist;
idx = i;
}
}
if (ans == 0x3f3f3f3f)
printf("disjoint\n");
else printf("%d %d\n", idx, ans);
}
return 0;
}
方法二:dijkstra。
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=105;
const int inf=0x5fffffff;
int Map[maxn][maxn],dist[maxn],p[maxn];
int n,m;
void initial_map() //初始化图,用邻接矩阵建图,空间复杂度为O(n^2)
{
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) Map[i][j]=0;
else Map[i][j]=inf;
}
}
for(int i=1;i<=n;i++){
int t,v,w;
scanf("%d",&t);
while(t--){
scanf("%d%d",&v,&w);
Map[i][v]=w;
}
}
}
void Dijkstra(int s) //以s为源点的单源最短路
{
memset(p,0,sizeof(p));
for(int i=1;i<=n;i++){
dist[i]=Map[s][i];
}
dist[s]=0;
p[s]=1;
int i,j,k,Min;
for(i=1;i<=n-1;i++){
Min=inf,k=s;
for(j=1;j<=n;j++){
if(!p[j]&&Min>dist[j]){ //我艹,把符号写反了,3wa
Min=dist[j];
k=j;
}
}
if(k==s) return;
p[k]=1;
for(j=1;j<=n;j++){ //松弛操作,更新
if(!p[j]&&Map[k][j]!=inf&&dist[j]>dist[k]+Map[k][j]){
dist[j]=dist[k]+Map[k][j];
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)==1){
if(n==0) break;
initial_map();
int maxLength=-inf,minTrans=inf,fastTrans=1;
for(int i=1;i<=n;i++){
maxLength=0;
Dijkstra(i); //以每个节点为源点的单源最短路
for(int j=1;j<=n;j++){
if(dist[j]>maxLength){
maxLength=dist[j];
}
}
if(maxLength<minTrans){
fastTrans=i;
minTrans=maxLength;
}
}
if(minTrans==inf){ //不可以达到
printf("disjoint\n");
}else{
printf("%d %d\n",fastTrans,minTrans);
}
}
return 0;
}
方法三:bellman-ford。转载自http://blog.csdn.net/became_a_wolf/article/details/47777241
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #define INF 10000000
- using namespace std;
- struct node
- {
- int u,v,w;
- }edge[2000];
- int n,num;
- int low[2000];
- int path[2000];
- int Bellman(int u0)
- {
- for(int i=0;i<=n;i++)
- low[i]=INF;
- low[u0]=0;
- for(int i=0;i<n-1;i++)
- {
- int flag=0;
- for(int j=0;j<num;j++)
- {
- if(low[edge[j].u]!=INF && edge[j].w+low[edge[j].u]<low[edge[j].v])
- {low[edge[j].v]=edge[j].w+low[edge[j].u];
- flag=1;
- }
- }
- if(flag==0)
- break;
- }
- int Max=-1;
- for(int i=1;i<=n;i++)
- if(Max<low[i])
- Max=low[i];
- return Max;
- }
- int main()
- {
- while(~scanf("%d",&n))
- {
- if(n==0)
- break;
- num=0;
- for(int i=1;i<=n;i++) //从1开始
- {
- int m;
- scanf("%d",&m);
- for(int j=1;j<=m;j++)
- {
- int x,t;
- scanf("%d%d",&x,&t);
- edge[num].u=i;
- edge[num].v=x;
- edge[num++].w=t;
- }
- }
- int Min=INF,biao=-1;
- for(int i=1;i<=n;i++)
- {
- int k=Bellman(i);
- if(Min>k)
- {Min=k;
- biao=i;
- }
- }
- if(biao==-1)
- printf("disjoint\n");
- else
- printf("%d %d\n",biao,Min);
- }
- }
方法四:spfa。转载自http://blog.csdn.net/acblacktea/article/details/50494069