zoj 1082 && poj 1125 && 南阳oj 426 Stockbroker Grapevine
2015-03-05 12:07
567 查看
题意:选定一个经纪人散步传闻,计算所有经纪人都收到这个过程的最少时间。
思路:求解n次单源最短路径,取单源最短路径中的最大值,使最大值最小。
poj上的数据很水,南阳oj的数据有所加强 http://acm.nyist.net/JudgeOnline/problem.php?pid=426
求单源最短路径之前,先判连通,若从一点无法走到其他所有点,则没必要从这个点出发,可以直接考虑其他点。
spfa代码:
优先队列+dijkstra:
思路:求解n次单源最短路径,取单源最短路径中的最大值,使最大值最小。
poj上的数据很水,南阳oj的数据有所加强 http://acm.nyist.net/JudgeOnline/problem.php?pid=426
求单源最短路径之前,先判连通,若从一点无法走到其他所有点,则没必要从这个点出发,可以直接考虑其他点。
spfa代码:
#include <iostream> #include <cstdio> #include <vector> #include <queue> using namespace std; const int inf = 100000; const int maxn = 1005; struct node{ int v; int w; node(int _v, int _w){ v = _v; w = _w; } }; int n; vector<node> list[maxn]; int dist[maxn]; bool inq[maxn]; bool vis[maxn]; bool input(){ scanf("%d",&n); if(n == 0) return false; //clear for(int i = 1 ; i <= n; i++) list[i].clear(); int m; int v,w; for(int i = 1; i <= n; i++){ scanf("%d",&m); for(int j = 0; j < m; j++){ scanf("%d%d",&v,&w); list[i].push_back(node(v,w)); } } return true; } void spfa(int s){ queue<int> q; for(int i = 1; i <= n; i++){ dist[i] = inf; inq[i] = false; } dist[s] = 0; q.push(s); while(!q.empty()){ int u = q.front(); q.pop(); inq[u] = false; for(int i = 0; i < list[u].size(); i++){ int v = list[u][i].v; int edge = list[u][i].w; if(dist[u] + edge < dist[v]){ dist[v] = dist[u] + edge; if(!inq[v]){ q.push(v); inq[v] = true; } } } }//end of while } void dfs(int s){ vis[s] = true; for(int i = 0; i < list[s].size(); i++){ int v = list[s][i].v; if(!vis[v]){ dfs(v); } } } void solve(){ int minimum = inf; int pos; for(int i = 1; i <= n; i++){ //dfs判连通 for(int j = 1; j <= n; j++) vis[j] = false; dfs(i); bool fg = false; for(int j = 1; j <= n; j++) if(!vis[j]){ fg = true; break; } if(fg) continue; spfa(i); int maximum = -inf; for(int j = 1; j <= n; j++){ if(dist[j] > maximum) maximum = dist[j]; if(maximum == inf) break;//不能全部收到传闻 } if(maximum != inf && maximum < minimum){ minimum = maximum; pos = i; } }//end of for if(minimum == inf) puts("disjoint\n"); else printf("%d %d\n",pos,minimum); } int main(){ while(input()){ solve(); } return 0; }
优先队列+dijkstra:
#include <iostream> #include <cstdio> #include <queue> using namespace std; const int inf = 100000; const int maxn = 1005; struct node{ int v; int w; node *next; node(){ v = 0; w = 0; next = NULL; } }; struct qnode{//为优先队列使用 int w; int index; qnode(int _w, int _index){ w = _w; index = _index; } bool operator < (const qnode &b) const{ return w > b.w; } }; int n; node* list[maxn]; int dist[maxn]; bool vis[maxn]; //dijkstra算法是否访问过 bool vis2[maxn]; //dfs void list_init(){//对每个链建立一个哨兵 for(int i = 0; i < maxn; i++) list[i] = new node; } void list_clear(){ for(int i = 0; i <= n; i++){ node *p = list[i]; while(p->next){ node *t = p->next; p->next = t->next; delete t; } } } bool input(){ scanf("%d",&n); if(n == 0) return false; //clear list_clear(); int m; int v,w; for(int i = 1; i <= n; i++){ scanf("%d",&m); node *p = list[i];//哨兵 for(int j = 0; j < m; j++){ node *t = new node; scanf("%d%d",&t->v,&t->w); //头插 t->next = p->next; p->next =t; } } return true; } void dijkstra(int s){ priority_queue<qnode> q; for(int i = 1; i <= n; i++){ dist[i] = inf; vis[i] = false; } dist[s] = 0; q.push(qnode(0,s)); while(!q.empty()){ int u = q.top().index; q.pop(); if(vis[u]) continue; vis[u] = true; node *p = list[u]->next; while(p){ int v = p->v; int edge = p->w; if(!vis[v] && dist[u] + edge < dist[v]){ dist[v] = dist[u] + edge; q.push(qnode(dist[v],v)); } p = p->next; } }//end of while } void dfs(int s){ vis2[s] = true; node *p = list[s]->next; while(p){ int v = p->v; if(!vis2[v]){ dfs(v); } p = p->next; } } void solve(){ int minimum = inf; int pos; for(int i = 1; i <= n; i++){ //dfs判断能否走通 for(int j = 1; j <= n; j++) vis2[j] = false; dfs(i); bool fg = false; for(int j = 1; j <= n; j++) { if(vis2[j] == false) { fg = true; break; } } if(fg) continue; dijkstra(i); int maximum = -inf; for(int j = 1; j <= n; j++){ if(dist[j] > maximum) maximum = dist[j]; if(maximum == inf) break;//不能全部收到传闻 } if(maximum != inf && maximum < minimum){ minimum = maximum; pos = i; } }//end of for if(minimum == inf) puts("disjoint\n"); else printf("%d %d\n",pos,minimum); } int main(){ list_init(); while(input()){ solve(); } return 0; }
相关文章推荐
- ZOJ-1082-Stockbroker Grapevine(最短路径)
- poj 1125 Stockbroker Grapevine
- ZOJ 1082 Stockbroker Grapevine
- POJ 1125 Stockbroker Grapevine(最短路&Floyd)
- zoj 1082 Stockbroker Grapevine
- ZOJ Problem Set - 1082 Stockbroker Grapevine
- zoj1082 Stockbroker Grapevine
- zoj 1082 - Stockbroker Grapevine
- zoj 1082 Stockbroker Grapevine 最短路 Dijkstra
- zoj 1082 Stockbroker Grapevine
- poj&nbsp;1125&nbsp;Stockbroker&nbsp;Grapevine(f…
- ZOJ 1082 Stockbroker Grapevine 最短路
- zoj 1082 Stockbroker Grapevine
- ZOJ Problem Set - 1082 Stockbroker Grapevine
- zoj 1082 Stockbroker Grapevine(最短路)
- POJ 百练 1125: Stockbroker Grapevine
- POJ 1125 Stockbroker Grapevine(最短路径Floyd算法)
- POJ 1125 Stockbroker Grapevine
- poj 1125 Stockbroker Grapevine 最短路Floyd算法
- poj 1125 Stockbroker Grapevine