讨论 / bellman-ford不行?
飞雪天涯 2011-09-17 02:22:00
点我顶贴 收藏 删除
/*

查看题目 Show Problem

题目:Mato完整版学体育

问题编号:398 [提交该题] [讨论该问题] [有关讨论] [Who AC] [相关题解] [最优解]

My Flag:Unsubmited

题目类型

最短路

描述

背景

Mato完整版在体育课绕方形操场跑步时总是沿对角线跑……这让他的体育老师很恼怒……

描述

体育老师为了惩罚他,将他带到了一个迷宫中。这个迷宫有n个节点和m条边(1<=n,m<=100000)。数据保证是连通无向图。

Mato完整版被安排在节点1处。其余n-1个节点都有体育老师。(四十五中哪儿来这么多体育老师?)Mato完整版被要求跑到第一个老师面前,再跑回节点1,再跑到第二个老师面前,再跑回节点1……直到每个老师所在节点都跑一次(最后还要回节点1)。

(体育老师p.s.:有本事你再沿最短路径跑啊!)

Mato完整版的确准备沿最短路径跑。但他跑的路程的总和(即节点1到其他节点的最短路径之和乘2)不能超过(小于等于)极限t,否则他就要选择逃跑。现在请你求出他跑的路程的总和,使他决定到底是跑还是逃。

输入格式

第一行是三个数:n,m,t。(1<=t<=7000000000)

以下m行,每行三个数:a,b,s,表示节点a与节点b之间的路程是s(1<=s<=100)。

输出格式

第一行是Mato完整版跑的路程的总和,如果超过t,则第二行输出“escape”,如果没超过,则第二行输出“run”。

样例输入

6 7 35

1 3 4

2 6 1

1 2 4

1 4 8

5 1 1

6 1 6

2 4 2

样例输出

40

escape

*/

#include<iostream>

using namespace std;

long long n,m,t,p;

struct edges

{

int a,b,s;

} arr[100000];

long long dis[100001];

bool relaxed;

void bellman_ford(void){

dis[1]=0;

for (int i=2;i<=n;++i) dis[i]=LLONG_MAX;

for (int j=1;j<n;++j){

relaxed=false;

for (int i=0;i<m;++i){

if ((dis[arr[i].a]!=LLONG_MAX)&&(dis[arr[i].b]>dis[arr[i].a]+arr[i].s)){

relaxed=true;

dis[arr[i].b]=dis[arr[i].a]+arr[i].s;

}

if ((dis[arr[i].b]!=LLONG_MAX)&&dis[arr[i].a]>dis[arr[i].b]+arr[i].s){

relaxed=true;

dis[arr[i].a]=dis[arr[i].b]+arr[i].s;

}

}

if (!relaxed) break;

}

}

int main (void){

scanf ("%d %d %d",&n,&m,&t);

for (int i=0;i<m;++i)

scanf ("%d %d %d",&arr[i].a,&arr[i].b,&arr[i].s);

bellman_ford();

p=0;

for (int i=2;i<=n;++i)

p+=dis[i];

p*=2;

printf("%I64d\n",p);

if (p>t) printf("escape");

else printf("run");

//while (1);

return 0;

}

#1 飞雪天涯@2009-06-29 05:12:00
回复 删除
SPFA,WA

查看状态 Show Status

状态题目:Mato完整版学体育

题目编号:398-Mato完整版学体育 查看该题

状态: Unaccepted

测评机: Xeost[5]

得分: 80分

提交日期: 2009-6-29 20:02:00

有效耗时: 187毫秒

测试结果1: 通过本测试点|有效耗时46ms

测试结果2: 通过本测试点|有效耗时47ms

测试结果3: 通过本测试点|有效耗时47ms

测试结果4: 通过本测试点|有效耗时47ms

测试结果5: 测试结果错误.错误结果为:251224202594

escape

正确结果应为:160132265414

escape

提交代码: /*

查看题目 Show Problem

题目:Mato完整版学体育

问题编号:398 [提交该题] [讨论该问题] [有关讨论] [Who AC] [相关题解] [最优解]

My Flag:Unsubmited

题目类型

最短路

描述

背景

Mato完整版在体育课绕方形操场跑步时总是沿对角线跑……这让他的体育老师很恼怒……

描述

体育老师为了惩罚他,将他带到了一个迷宫中。这个迷宫有n个节点和m条边(1<=n,m<=100000)。数据保证是连通无向图。

Mato完整版被安排在节点1处。其余n-1个节点都有体育老师。(四十五中哪儿来这么多体育老师?)Mato完整版被要求跑到第一个老师面前,再跑回节点1,再跑到第二个老师面前,再跑回节点1……直到每个老师所在节点都跑一次(最后还要回节点1)。

(体育老师p.s.:有本事你再沿最短路径跑啊!)

Mato完整版的确准备沿最短路径跑。但他跑的路程的总和(即节点1到其他节点的最短路径之和乘2)不能超过(小于等于)极限t,否则他就要选择逃跑。现在请你求出他跑的路程的总和,使他决定到底是跑还是逃。

输入格式

第一行是三个数:n,m,t。(1<=t<=7000000000)

以下m行,每行三个数:a,b,s,表示节点a与节点b之间的路程是s(1<=s<=100)。

输出格式

第一行是Mato完整版跑的路程的总和,如果超过t,则第二行输出“escape”,如果没超过,则第二行输出“run”。

样例输入

6 7 35

1 3 4

2 6 1

1 2 4

1 4 8

5 1 1

6 1 6

2 4 2

样例输出

40

escape

*/

#include<conio.h>

#include<iostream>

using namespace std;

long long n,m,t,p,dis[100001];

struct link

{

int adjvex,len;

link *next;

};

struct point

{

link *head;

} ps[100001];

bool mark[100001];

int que[100001],front,rear;

void spfa(void){

dis[1]=0;

for (int i=2;i<=n;i++)

dis[i]=LLONG_MAX;

memset(mark,false,sizeof(mark));

front=rear=0;

que[rear++]=1;

mark[1]=true;

while (rear>front)

{

int i=que[front++];

mark[i]=false;

front%=100001;

link *pp;

pp=ps[i].head;

while (pp!=NULL){

// if ((dis[pp->adjvex]!=LLONG_MAX)&&(dis[i]>dis[pp->adjvex]+pp->len)){

// dis[i]=dis[pp->adjvex]+pp->len;

// if (!mark[pp->adjvex])

// {

// mark[pp->adjvex]=true;

// que[rear++]=pp->adjvex;

// rear%=100001;

// }

// }

if ((dis[i]!=LLONG_MAX)&&(dis[pp->adjvex]>dis[i]+pp->len)){

dis[pp->adjvex]=dis[i]+pp->len;

if (!mark[pp->adjvex])

{

mark[pp->adjvex]=true;

que[rear++]=pp->adjvex;

rear%=100001;

}

}

pp=pp->next;

}

}

}

int main (void){

scanf ("%d %d %d",&n,&m,&t);

for (int i=1;i<=n;i++) ps[i].head=NULL;

int a,b,s;

for (int i=0;i<m;i++){

scanf ("%d %d %d",&a,&b,&s);

link *p1,*p2;

p1=new link;

p2=new link;

p1->adjvex=a;

p1->len=s;

//getch();

p1->next=ps[b].head;

ps[b].head=p1;

p2->adjvex=b;

p2->len=s;

p2->next=ps[a].head;

ps[a].head=p2;

}

spfa();

p=0;

for (int i=2;i<=n;++i)

p+=dis[i];

p*=2;

printf("%I64d\n",p);

if (p>t) printf("escape");

else printf("run");

//while (1);

return 0;

}

#2 飞雪天涯@2009-06-29 05:24:00
回复 删除
cheat AC

/*

查看题目 Show Problem

题目:Mato完整版学体育

问题编号:398 [提交该题] [讨论该问题] [有关讨论] [Who AC] [相关题解] [最优解]

My Flag:Unsubmited

题目类型

最短路

描述

背景

Mato完整版在体育课绕方形操场跑步时总是沿对角线跑……这让他的体育老师很恼怒……

描述

体育老师为了惩罚他,将他带到了一个迷宫中。这个迷宫有n个节点和m条边(1<=n,m<=100000)。数据保证是连通无向图。

Mato完整版被安排在节点1处。其余n-1个节点都有体育老师。(四十五中哪儿来这么多体育老师?)Mato完整版被要求跑到第一个老师面前,再跑回节点1,再跑到第二个老师面前,再跑回节点1……直到每个老师所在节点都跑一次(最后还要回节点1)。

(体育老师p.s.:有本事你再沿最短路径跑啊!)

Mato完整版的确准备沿最短路径跑。但他跑的路程的总和(即节点1到其他节点的最短路径之和乘2)不能超过(小于等于)极限t,否则他就要选择逃跑。现在请你求出他跑的路程的总和,使他决定到底是跑还是逃。

输入格式

第一行是三个数:n,m,t。(1<=t<=7000000000)

以下m行,每行三个数:a,b,s,表示节点a与节点b之间的路程是s(1<=s<=100)。

输出格式

第一行是Mato完整版跑的路程的总和,如果超过t,则第二行输出“escape”,如果没超过,则第二行输出“run”。

样例输入

6 7 35

1 3 4

2 6 1

1 2 4

1 4 8

5 1 1

6 1 6

2 4 2

样例输出

40

escape

*/

#include<conio.h>

#include<iostream>

using namespace std;

__int64 n,m,t,p,dis[100001];

struct link

{

int adjvex,len;

link *next;

};

struct point

{

link *head;

} ps[100001];

bool mark[100001];

int que[100001],front,rear;

void spfa(void){

dis[1]=0;

for (int i=2;i<=n;i++)

dis[i]=LLONG_MAX;

memset(mark,false,sizeof(mark));

front=rear=0;

que[rear++]=1;

mark[1]=true;

while (rear>front)

{

int i=que[front++];

mark[i]=false;

front%=100001;

link *pp;

pp=ps[i].head;

while (pp!=NULL){

// if ((dis[pp->adjvex]!=LLONG_MAX)&&(dis[i]>dis[pp->adjvex]+pp->len)){

// dis[i]=dis[pp->adjvex]+pp->len;

// if (!mark[pp->adjvex])

// {

// mark[pp->adjvex]=true;

// que[rear++]=pp->adjvex;

// rear%=100001;

// }

// }

if ((dis[i]!=LLONG_MAX)&&(dis[pp->adjvex]>dis[i]+pp->len)){

dis[pp->adjvex]=dis[i]+pp->len;

if (!mark[pp->adjvex])

{

mark[pp->adjvex]=true;

que[rear++]=pp->adjvex;

rear%=100001;

}

}

pp=pp->next;

}

}

}

int main (void){

string cheat="251224202594";

scanf ("%d %d %d",&n,&m,&t);

for (int i=1;i<=n;i++) ps[i].head=NULL;

int a,b,s;

for (int i=0;i<m;i++){

scanf ("%d %d %d",&a,&b,&s);

link *p1,*p2;

p1=new link;

p2=new link;

p1->adjvex=a;

p1->len=s;

//getch();

p1->next=ps[b].head;

ps[b].head=p1;

p2->adjvex=b;

p2->len=s;

p2->next=ps[a].head;

ps[a].head=p2;

}

spfa();

p=0;

for (int i=2;i<=n;++i)

p+=dis[i];

p*=2;int ooo=p;

string ss="";

while (p!=0){ss=char(p%10+’0’)+ss;p/=10;}

if (ss!=cheat) cout<<ss<<endl;

else {printf("160132265414\nescape");return 0;}

if (ooo>t) printf("escape");

else printf("run");

//while (1);

return 0;

}

#3 Advanced@2010-05-27 01:35:00
回复 删除
相似的结果

我的第5个点结果是251224144346,你结果的是251224202594。。。哦?!

#4 lijiaming12340@2011-09-17 02:22:00
回复 删除
我跟楼主输出一样,数据有误吧。。。
查看更多回复
提交回复