给一个有向图
以i为出发起点,可以计算得到 i到所有点的最短路,取一个最大值 MAXi
问 以谁为起点,得到的MAXi最小,输出起点编号和MAXi
思路:
就是对每个人求一次最短路, 做n次spfa,
POJ的数据太水了,随便过。。。NYOJ的数据 n=1000
n次dji+STL优先队列+vector建邻接表会超时 ,邻接表得自己实现才勉强过一秒
最快的是用spfa+自己实现邻接表
针对本题还有一个非常重要的地方,做spfa前先dfs求一遍连通性,不连通直接continue,不加这部会超时。。。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <set> #include <vector> using namespace std; int n,m; struct node { int x,v; node(){} node(int a,int b) { x=a; v=b; } }; struct EDGE { int u;//起点 int v;//终点 int len;//边的长度 int next; }edge[1005*105+1];//一定要边的范围 int head [1005];//头节点 int k=1; void init()//初始化信息,-1; { for(int i=1;i<=n;i++) head[i]=-1; k=1; } //插入边 void insert(int u,int v,int len) { edge[k].v=v; edge[k].len=len; edge[k].next=head[u];head[u]=k;k++;//正边 // edge[k].v=u; edge[k].len=len; edge[k].next=head[v];head[v]=k;k++;//反边 } int dis[1005]; int vis[1005]; queue<node> q; const int inf=2147483647; int st,ed; int vis333[1005]; int flag; int dfs(int x) { int i; vis333[x]=1; for( i=head[x];i!=-1;i=edge[i].next) { int t=edge[i].v; if (!vis333[t]) { dfs(t); } } return 0; } int main() { void spfa( ); int i,j; int x,y; while(cin>>n&&n) { int num; init(); for (i=1;i<=n;i++) { scanf("%d",&num); for (j=1;j<=num;j++) { scanf("%d%d",&x,&y); //mp[i].push_back(node(x,y)); insert(i,x,y); } } node minn,maxx; minn.v=inf; for (i=1;i<=n;i++) //n次 { flag=0; for (j=1;j<=n;j++) vis333[j]=0; dfs(i); for (j=1;j<=n;j++) if (!vis333[j]) { flag=1; break; } if (flag) continue; st=i; spfa(); maxx.v=0; for (j=1;j<=n;j++) { if (dis[j]>maxx.v) { maxx.v=dis[j]; maxx.x=i;// x记录的是 当前方案总耗时 对应的 出发点i } } //maxx得到为 i 开始传播,到全部人 的总耗时 if (maxx.v<minn.v) minn=maxx; //minn记录的是 所有完成传播任务的 耗时的最小值 } if (minn.v==inf) //图是非联通的 printf("disjoint\n"); else printf("%d %d\n",minn.x,minn.v); } return 0; } void spfa() { while(!q.empty()) q.pop(); int i; for (i=1;i<=n;i++) { dis[i]=inf; vis[i]=0; } dis[st]=0; //vis[st]=1; q.push(node(st,0)); while(!q.empty()) { node tmp=q.front(); q.pop(); int tt=tmp.x; vis[tt]=0; //for (i=0;i<mp[tt].size();i++) for(int i=head[tt];i!=-1;i=edge[i].next) { // int x=mp[tt][i].x; // int v=mp[tt][i].v; int x=edge[i].v; int v=edge[i].len; if (dis[tt]+v<dis[x]) { dis[x]=dis[tt]+v; if (!vis[x]) { q.push(node(x,dis[x])); vis[x]=1; } } } } }