您的位置:首页 > 其它

poj3259(Bellman_ford)

2013-05-30 11:04 127 查看
http://poj.org/problem?id=3259



Wormholes

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 20180Accepted: 7159
Description

While exploring his many farms, Farmer John has discovered a
number of amazing wormholes. A wormhole is very peculiar because it
is a one-way path that delivers you to its destination at a time
that is BEFORE you entered the wormhole! Each of FJ's farms
comprises N (1 ≤ N ≤ 500) fields conveniently
numbered 1..N, M (1 ≤ M ≤ 2500) paths, and
W (1 ≤ W ≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the
following: start at some field, travel through some paths and
wormholes, and return to the starting field a time before his
initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will
supply you with complete maps to F (1 ≤ F ≤ 5) of his
farms. No paths will take longer than 10,000 seconds to travel and
no wormhole can bring FJ back in time by more than 10,000
seconds.

Input

Line 1: A single integer,
F. F farm descriptions follow.

Line 1 of each farm: Three space-separated integers respectively:
N, M, and W

Lines 2..M+1 of each farm: Three space-separated numbers
(S, E, T) that describe, respectively: a
bidirectional path between S and E that requires
T seconds to traverse. Two fields might be connected by more
than one path.

Lines M+2..M+W+1 of each farm: Three
space-separated numbers (S, E, T) that
describe, respectively: A one way path from S to E
that also moves the traveler back T seconds.
Output

Lines 1..F: For each
farm, output "YES" if FJ can achieve his goal, otherwise output
"NO" (do not include the quotes).
Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES

Hint

For farm 1, FJ cannot travel
back in time.

For farm 2, FJ could travel back in time by the cycle
1->2->3->1, arriving
back at his starting location 1 second before he leaves. He could
start from anywhere on the cycle to accomplish this.
Source

USACO 2006 December Gold

题意:还是最短路径问题,不过这题加了虫洞使得图中可以出现负权值,这就不能用dijkstra,可以用bellman_ford来处理带负权值的最短路径。http://baike.baidu.com/view/1481053.htm
http://blog.sina.com.cn/s/blog_792e6df50100whcn.html
#include<stdio.h>

#include<string.h>

#define INF 20000 //此处要特别注意,bellman-ford算法中不要使用0x7fffffff

#define num 501

int
path[num][num];//path[][]保存路径

int
dis[num];//保存距离

bool
bellman_ford(int
size)//调用bellman_ford求含负权值的最短路径

{

int
i,j,k;

bool flag;

for(i=2;i<=size;i++)//其余点的距离设置为无穷

dis[i]=INF;

dis[1]=0;//关键//源点的距离设置为0

for(k=1;k<size;k++)

{

flag=false;//优化:如果某次迭代中没有任何一个dis值改变,尽可以立刻退出迭代而不需要把所有的n-1次迭代都做完

for(i=1;i<=size;i++)

{

for(j=1;j<=size;j++)

{

if(dis[i]!=INF&&path[i][j]!=INF&&dis[j]>dis[i]+path[i][j])

{

dis[j]=dis[i]+path[i][j];

flag=true;

}

}

}

if(!flag)

break;

}

for(i=1;i<=size;i++)//重复进行n-1次收缩

{

for(j=1;j<=size;j++)

{

if(dis[i]!=INF&&path[i][j]!=INF&&dis[j]>dis[i]+path[i][j])

return true;

}

}

return false;

}

int main()

{

int f;

int
n,m,w;

int
s,e,t;

int i,j;

scanf("%d",&f);//测试组数

while(f--)

{

scanf("%d %d
%d",&n,&m,&w);//n个点,m条边,w个虫洞

for(i=1;i<=n;i++)//初始化路径长度为无穷大

{

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

path[i][j]=INF;

}

for(i=1;i<=m;i++)//输入m条边

{

scanf("%d %d
%d",&s,&e,&t);//s弧头,e弧尾,t权值||距离||时间

if(path[s][e]>t)

path[s][e]=path[e][s]=t;

}

for(i=1;i<=w;i++)//m个虫洞

{

scanf("%d %d
%d",&s,&e,&t);//s虫洞的弧头,e虫洞的弧尾,t权值||距离||时间(这里是负权值)

path[s][e]=(-1)*t;

}

if(bellman_ford(n))//调用bellman_ford()求最短路径(含负权值)

{

printf("YES\n");

}

else

printf("NO\n");

}

return 0;

}




代码2:来自warush http://blog.sina.com.cn/s/blog_7c2a1aa30100qc9n.html
#include<stdio.h>

#include<string.h>

#define MAX 8000

#define inf 0x7f7f7f7f

typedef struct

{

int x;

int y;

int w;

}Edge; Edge
edges[MAX];

int
dis[505];

int
N,M,W,e;

bool bellman_ford()

{

int i,j;

bool flag;

for(i=2;i<=N;i++)

dis[i]=inf;

dis[1]=0;

for(i=1;i<N;i++)

{

flag=true;

for(j=1;j<=e;j++)

{

if(dis[edges[j].y
]>dis[edges[j].x]+edges[j].w
)

{

flag=0;

dis[edges[j].y
]=dis[edges[j].x
]+edges[j].w
;

}

}

if(flag)

return true;

}

for(i=1;i<=e;i++)

{

if(dis[edges[i].y
]>dis[edges[i].x]+edges[i].w)

return 0;

}

return 1;

}

int main()

{

int T;

int i;

int
t1,t2,t3;

scanf("%d",&T);

while(T--)

{

e=0;

scanf("%d %d
%d",&N,&M,&W);

for(i=1;i<=M;i++)

{

scanf("%d %d
%d",&t1,&t2,&t3);

e++;

edges[e].x=t1;

edges[e].y=t2;

edges[e].w=t3;

e++;

edges[e].x=t2;

edges[e].y=t1;

edges[e].w=t3;

}

for(i=1;i<=W;i++)

{

scanf("%d %d
%d",&t1,&t2,&t3);

e++;

edges[e].x=t1;

edges[e].y
=t2;

edges[e].w
=-t3;

}

if(bellman_ford())

{

printf("NO\n");

}

else

printf("YES\n");

}

return 0;

}




2012.9.3

#include<cstdio>

#include<iostream>

using namespace std;

const int point_maxn=505;

const int edge_maxn=5500;

const int inf=1000000;

int dis[point_maxn];

struct

{

int u;

int v;

int w;

}edge[edge_maxn];

int point_num,edge_num;

int bellman_ford()

{

int i,j;

for(i=2;i<=point_num;i++)

{

dis[i]=inf;

}

dis[1]=0;

for(i=1;i<=point_num-1;i++)

{

for(j=1;j<=edge_num;j++)

{

int
u=edge[j].u;

int
v=edge[j].v;

int
w=edge[j].w;

if(dis[v]>dis[u]+w)

{

dis[v]=dis[u]+w;

}

}

}

for(i=1;i<=edge_num;i++)

{

int u=edge[i].u;

int v=edge[i].v;

int w=edge[i].w;

if(dis[v]>dis[u]+w)

return
false;

}

return true;

}

int main()

{

int n,m,hole;

int u,v,w;

int f;

scanf("%d",&f);

while(f--)

{

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

int i,k=0;

for(i=1;i<=m;i++)

{

scanf("%d%d%d",&u,&v,&w);//注意是重边

k++;

edge[k].u=u;

edge[k].v=v;

edge[k].w=w;

k++;

edge[k].u=v;

edge[k].v=u;

edge[k].w=w;

}

for(i=1;i<=hole;i++)

{

scanf("%d%d%d",&u,&v,&w);

k++;

edge[k].u=u;

edge[k].v=v;

edge[k].w=-w;

}

edge_num=k;

point_num=n;

if(!bellman_ford())

{

printf("YES\n");

}

else

printf("NO\n");

}

return 0;

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