Bzoj1715蟲洞
阿新 • • 發佈:2018-09-17
git sfpa bsp style 但是 tab 清晰 table 連接
試題描述 |
John 在他的農場中閑逛時發現了許多蟲洞。蟲洞可以看作一條十分奇特的有向邊,並可以使你返回到過去的一個時刻(相對你進入蟲洞之前)。John 的每個農場有 M 條小路(無向邊)連接著 N(從 1 到 N 標號)塊地,並有 W 個蟲洞。 現在 John 想借助這些蟲洞來回到過去(在出發時刻之前回到出發點),請你告訴他能辦到嗎。 John 將向你提供 F 個農場的地圖。沒有小路會耗費你超過 10^4秒的時間,當然也沒有蟲洞回幫你回到超過 10^4秒以前。 |
輸入 |
第一行一個整數 F,表示農場個數; 對於每個農場: 第一行,三個整數 N,M,W; 接下來 M 行,每行三個數 S,E,T,表示在標號為 S 的地與標號為 E 的地中間有一條用時 T 秒的小路; 接下來 W 行,每行三個數 S,E,T,表示在標號為 S 的地與標號為 E 的地中間有一條可以使 John 到達 T 秒前的蟲洞。 |
輸出 |
輸出共 F 行,如果 John 能在第 i 個農場實現他的目標,就在第 i 行輸出 YES,否則輸出 NO。 |
輸入示例 |
2 3 3 1 1 2 2 1 3 4 2 3 1 3 1 3 1 2 3 2 3 4 3 1 8 |
輸出示例 |
NO YES |
其他說明 |
對於全部數據,1≤F≤5,1≤N≤500,1≤M≤2500,1≤W≤200,1≤S,E≤N,∣T∣≤104。 |
題目描述還是很清晰的,大概就是給一個圖,判斷圖中是否存在負環,簡單的一個SPFA就可以跑
然而要註意的是,這道題用普通的BFS會被卡(不知道SLF能不能過,有興趣的同學可以試一下)
判斷負環的方法很簡單,如果我們發現一個點已經被更新過了,但是dis值卻比當前點還要小,就證明它從這個點出發後,跑了一個小於零的路徑又回到了原點,證明有負環
下面給出代碼
#include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #define cl(a) memset(a,0,sizeof(a)) using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch==‘-‘) f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; return x*f; } inline void write(int x){ if(x<0) putchar(‘-‘),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); return ; } int T; int n,m,w; int total=0; int head[10006],nxt[10006],to[10006],v[10006]; int dis[1006]; void add(int x,int y,int z){ total++; to[total]=y; v[total]=z; nxt[total]=head[x]; head[x]=total; return ; } int book[1006]; int f=0; void SPFA(int x){//DFS版的SFPA for(int e=head[x];e;e=nxt[e]){ if(dis[to[e]]>dis[x]+v[e]){ dis[to[e]]=dis[x]+v[e]; if(book[to[e]]){//如果一個點已經跑過了,但是值比原來還要小,就是負環 f=1; return ; } book[to[e]]=1; SPFA(to[e]); book[to[e]]=0; } } return ; } int main(){ T=rd(); while(T--){ f=0; total=0; cl(head),cl(nxt),cl(to),cl(v),cl(book); memset(dis,127,sizeof(dis)); n=rd(),m=rd(),w=rd(); for(int i=1;i<=m;i++){ int x,y,z; x=rd(),y=rd(),z=rd(); add(x,y,z); add(y,x,z); } for(int i=1;i<=w;i++){ int x,y,z; x=rd(),y=rd(),z=rd(); add(x,y,0-z);//蟲洞因為是往回倒時間,所以存成負數 } dis[1]=0; SPFA(1); if(f) printf("YES\n"); else printf("NO\n"); } return 0; }
Bzoj1715蟲洞