poj3259(Bellman_ford)

来源:互联网 发布:中标麒麟装软件 编辑:程序博客网 时间:2024/06/03 20:38

http://poj.org/problem?id=3259

 

Wormholes
Time Limit: 2000MSMemory Limit: 65536KTotal Submissions: 20180Accepted: 7159

Description

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

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

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

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: abidirectional path between S and E that requiresT seconds to traverse. Two fields might be connected by morethan one path.
Lines M+2..M+W+1 of each farm: Threespace-separated numbers (S, E, T) thatdescribe, respectively: A one way path from S to Ethat also moves the traveler back T seconds.

Output

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

Sample Input

23 3 11 2 21 3 42 3 13 1 33 2 11 2 32 3 43 1 8

Sample Output

NOYES

Hint

For farm 1, FJ cannot travelback in time.
For farm 2, FJ could travel back in time by the cycle1->2->3->1, arrivingback at his starting location 1 second before he leaves. He couldstart 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
intpath[num][num];//path[][]保存路径
int dis[num];//保存距离
boolbellman_ford(intsize)//调用bellman_ford求含负权值的最短路径
{
inti,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;
ints,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; Edgeedges[MAX];
intdis[505];
intN,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;
intt1,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++)
  {
    intu=edge[j].u;
    intv=edge[j].v;
    intw=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)
   returnfalse;
 }
 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;
}
原创粉丝点击