题目背景
我是源点,你是终点。我们之间有负权环。 ——小明
题目描述
在小明和小红的生活中,有N个关键的节点。有M个事件,记为一个三元组(Si,Ti,Wi),表示从节点Si有一个事件可以转移到Ti,事件的效果就是使他们之间的距离减少Wi。
这些节点构成了一个网络,其中节点1和N是特殊的,节点1代表小明,节点N代表小红,其他代表进展的阶段。所有事件可以自由选择是否进行,但每次只能进行当前节点邻接的。请你帮他们写一个程序,计算出他们之间可能的最短距离。
输入输出格式
输入格式:第1行,两个正整数N,M.
之后M行,每行3个空格隔开的整数Si,Ti,Wi。
输出格式:一行,一个整数表示他们之间可能的最短距离。如果这个距离可以无限缩小,输出“Forever love”(不含引号)。
输入输出样例
说明
对于20%数据,N<=10,M<=50。
对于50%数据,N<=300,M<=5000。
对于全部数据,N<=1000,M<=10000,|Wi|<=100,保证从节点1到N有路径。
负环练习+1s
看完了这弱智的题面我们不难发现这又是一道负环题。
然后我们发现没有什么奇怪的操作,这难道不就是一道模板题么?
然后我们兴奋的把模板给复制了过来,随便改了一下,交了上去。
然后0分?不,其实因为数据太水你有90分。
最初大家都以为是数据出了问题,开始特判,面向数据编程,找管理员投诉。
然后有几位dalao就发话了,只是因为人们的思想江化(枪毙名单上又有我的名字了)
不仅小明可以拉进距离,小红也可以。
所以只需要从1,和n点跑两次然后取最小值就好了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=10001;
struct edge
{
int next,node,w;
}h[MAXN];
int Head[MAXN],Dis[MAXN];
bool visit[MAXN],flag;
int n,m,tot;
void add(int u,int v,int w)
{
h[++tot].next=Head[u];
h[tot].node=v;
h[tot].w=w;
Head[u]=tot;
}
void SPFA(int x)
{
visit[x]=1;
if(flag)
return ;
for(int i=Head[x];i;i=h[i].next)
{
int v=h[i].node,w=h[i].w;
if(Dis[v]>Dis[x]+w)
{
if(visit[v])
{
flag=1;
return;
}
Dis[v]=Dis[x]+w;
visit[v]=1;
SPFA(v);
}
}
visit[x]=0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,-z);
}
memset(Dis,11,sizeof(Dis));
Dis[1]=0;
SPFA(1);
int ans=Dis[n];
memset(Dis,11,sizeof(Dis));
memset(visit,0,sizeof(visit));
Dis[n]=0;
SPFA(n);
ans=min(ans,Dis[1]);
if(flag)
cout<<"Forever love";
else
cout<<ans;
return 0;
}