洛谷 【P2136】拉進距離
阿新 • • 發佈:2018-11-08
題目背景
我是源點,你是終點。我們之間有負權環。 ——小明
題目描述
在小明和小紅的生活中,有N個關鍵的節點。有M個事件,記為一個三元組(Si,Ti,Wi),表示從節點Si有一個事件可以轉移到Ti,事件的效果就是使他們之間的距離減少Wi。
這些節點構成了一個網路,其中節點1和N是特殊的,節點1代表小明,節點N代表小紅,其他代表進展的階段。所有事件可以自由選擇是否進行,但每次只能進行當前節點鄰接的。請你幫他們寫一個程式,計算出他們之間可能的最短距離。
輸入輸出格式
輸入格式:第1行,兩個正整數N,M.
之後M行,每行3個空格隔開的整數Si,Ti,Wi。
輸出格式:一行,一個整數表示他們之間可能的最短距離。如果這個距離可以無限縮小,輸出“Forever love”(不含引號)。
輸入輸出樣例
輸入樣例#1:3 3 1 2 3 2 3 -1 3 1 -10輸出樣例#1:
-2
說明
對於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; }