1. 程式人生 > >bzoj1715 蟲洞

bzoj1715 蟲洞

存在 ctime 農場 ack bzoj 返回 size problem --

傳送門

題目

John在他的農場中閑逛時發現了許多蟲洞。蟲洞可以看作一條十分奇特的有向邊,並可以使你返回到過去的一個時刻(相對你進入蟲洞之前)。John的每個農場有M條小路(無向邊)連接著N (從1..N標號)塊地,並有W個蟲洞。其中1<=N<=500,1<=M<=2500,1<=W<=200。 現在John想借助這些蟲洞來回到過去(出發時刻之前),請你告訴他能辦到嗎。 John將向你提供F(1<=F<=5)個農場的地圖。沒有小路會耗費你超過10000秒的時間,當然也沒有蟲洞回幫你回到超過10000秒以前。

Input

* Line 1: 一個整數 F, 表示農場個數。

* Line 1 of each farm: 三個整數 N, M, W。

* Lines 2..M+1 of each farm: 三個數(S, E, T)。表示在標號為S的地與標號為E的地中間有一條用時T秒的小路。

* Lines M+2..M+W+1 of each farm: 三個數(S, E, T)。表示在標號為S的地與標號為E的地中間有一條可以使John到達T秒前的蟲洞。

Output

* Lines 1..F: 如果John能在這個農場實現他的目標,輸出"YES",否則輸出"NO"。

分析

經過認真讀題發現就是找是否存在負環就行了,spfa隨便做,但要註意所謂的蟲洞是有向邊!!!

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include
<stack> using namespace std; int vis[1100],n,d[1100],iq[1100];; vector<pair<int,int> >v[1100]; queue<int>q; inline bool spfa(){ int i,j,k; d[1]=0; q.push(1); iq[1]=1; vis[1]=1; while(!q.empty()){ int x=q.front(); q.pop(); for(i=0;i<v[x].size();i++){ int y=v[x][i].first,z=v[x][i].second; if(d[x]+z<d[y]){ d[y]=d[x]+z; if(!iq[y]){ vis[y]++; if(vis[y]>n)return 1; q.push(y); iq[y]=1; } } } iq[x]=0; } return 0; } int main() { int m,i,j,k,t,w,x,y,z; scanf("%d",&t); while(t--){ while(!q.empty())q.pop(); memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); memset(iq,0,sizeof(iq)); for(i=1;i<=1000;i++)v[i].clear(); scanf("%d%d%d",&n,&m,&w); for(i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); v[x].push_back(make_pair(y,z)); v[y].push_back(make_pair(x,z)); } for(i=1;i<=w;i++){ scanf("%d%d%d",&x,&y,&z); v[x].push_back(make_pair(y,-z)); } if(spfa())puts("YES"); else puts("NO"); } return 0; }

bzoj1715 蟲洞