poj3259(Bellman_ford)
2013-05-30 11:04
127 查看
http://poj.org/problem?id=3259
Wormholes
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
Sample Output
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;
}
Wormholes
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 20180 | Accepted: 7159 |
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;
}
相关文章推荐
- poj3259 Bellman_ford
- poj3259 bellman_ford 算法 判环 最短路
- poj3259( spfa 和 bellman_ford)
- POJ3259 Wormholes SPFA 或者 bellman_ford
- poj3259 Bellman_Ford
- POJ3259 Wormholes (Bellman-Ford最短路径算法)
- POJ3259 Wormholes 解题报告--bellman_ford
- poj3259 Bellman-Ford
- POJ3259——Wormholes(Bellman-Ford+SPFA)
- POJ3259 Wormholes (Bellman-Ford最短路径算法)
- [水]poj3259 (Bellman-ford)
- POJ3259 农场与虫洞 图论(Bellman-Ford求负环)
- POJ3259 Wormholes Bellman-Ford C语言
- POJ3259 Wormholes (Bellman-Ford最短路径算法)
- POJ3259《Wormholes》方法:Bellman-ford
- poj3259 Wormholes 图的负权回路判定,Bellman_Ford
- poj3259 bellman—ford
- POJ3259(Wormholes)(Bellman-Ford判断负权图 )
- 虫洞_poj3259_bellman_ford
- POJ3259 Wormholes(Bellman-ford 负环)