您的位置:首页 > 其它

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代码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: