题目大意是,F个农场,N点,m条无向边以及每两个连接的点要花费的时间,w条有向边,从一点到另一点可减少一定时间,问是否有可能问你从某个点开始走,能回到从前。
两种解法
spfa
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
//spfa
int head[605],d[605];
bool vis[605];
int use[605];
int n,m,w;
struct edge
{
int u,v,t;
int next;
}e[6000];
bool spfa()
{
for(int i=0;i<=n;i++)
{
d[i]=INF;
vis[i]=0;
use[i]=0;
}//初始化
queue<int>q;
//任取第一边的第一点存入
q.push(e[1].u);
vis[e[1].u]=1;
d[e[1].u]=0;
++use[e[1].u];//表示该点已经过一次
while(!q.empty())
{
int temp=q.front();
q.pop();
vis[temp]=0;
for(int i=head[temp];i!=-1;i=e[i].next)
{
if(d[e[i].v]>d[e[i].u]+e[i].t)
{
d[e[i].v]=d[e[i].u]+e[i].t;
if(!vis[e[i].v])
{
q.push(e[i].v);
if(++use[e[i].v]>=n)return 1;//入队次数超过总数,则存在回路
vis[e[i].v]=1;
}
}
}
}
return 0;
}
int main()
{
int f;
cin>>f;
while(f--)
{
cin>>n>>m>>w;
memset(head,-1,sizeof(head));
for(int i=1;i<=2*m;i+=2)
{
cin>>e[i].u>>e[i].v>>e[i].t;
e[i+1].v=e[i].u;
e[i+1].u=e[i].v;
e[i+1].t=e[i].t;
e[i].next=head[e[i].u];
head[e[i].u]=i;
e[i+1].next=head[e[i+1].u];
head[e[i+1].u]=i+1;
}
for(int i=2*m+1;i<=2*m+w;i++)
{
cin>>e[i].u>>e[i].v>>e[i].t;
e[i].t=-e[i].t;
e[i].next=head[e[i].u];
head[e[i].u]=i;
}
if(spfa())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
bellmanford
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
#define INF (1<<26)
using namespace std;
//bellman_ford
struct edge
{
int u,v,t;
}e[6000];
int n,m,w;
int dis[1005];
int bellman_ford()
{
for(int i=0;i<=n;i++)dis[i]=INF;
dis[1]=0;
for(int i=0;i<n-1;i++)
{
for(int j=0;j<2*m+w;j++)
{
int a=e[j].u;
int b=e[j].v;
int s=e[j].t;
if(dis[b]>dis[a]+s&&dis[a]<INF)dis[b]=dis[a]+s;//dis[a]必须<inf
}
}
for(int i=0;i<2*m+w;i++)
{
int a=e[i].u;
int b=e[i].v;
int s=e[i].t;
if(dis[b]>dis[a]+s&&dis[a]<INF)return 1;
}//重新遍历一次,看是否存在负权回路
return 0;
}
int main()
{
int f;
cin>>f;
while(f--)
{
cin>>n>>m>>w;
for(int i=0;i<2*m;i+=2)
{
cin>>e[i].u>>e[i].v>>e[i].t;
e[i+1].v=e[i].u;
e[i+1].u=e[i].v;
e[i+1].t=e[i].t;
}
int cnt=2*m;
for(int i=0;i<w;i++)
{
cin>>e[cnt+i].u>>e[cnt+i].v>>e[cnt+i].t;
e[cnt+i].t=-e[cnt+i].t;
}
if(bellman_ford())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
920

被折叠的 条评论
为什么被折叠?



