連結
題目描述 Description
揚帆遠洋為了打敗牧師妹醬,不惜一切代價通過各種各樣的手段得到了傳奇道具“れいじまいご”來釋放能量使得全球充滿揚帆遠洋的威嚴氣場和能量場。但是,“れいじまいご”釋放的能量只能在某個很小的地區中存在,為了使得效果可以逸散的全球,揚帆遠洋決定效仿心靈操控者——尤裡,在世界各地修建了N個“れいじまいご·ベクトル変換”使得其能量場可以在全世界張開。
根據電腦的計算結果,這N個地點大多都是非常偏僻的城鎮。因此,之間的道路並不定都是暢通的。這些地區之間通過R條道路串連,為了使得之間前往的方便,揚帆遠洋TEL還協助揚帆遠洋產生了P個空間隧道,揚帆遠洋稱之為“時間と空間の扉”。每條道路i或者“時間と空間の扉”i串連地區Ai到Bi,花費為Ci。道路是雙向的,可以從Ai到Bi,也可以從Bi到Ai,花費都是Ci。然而“時間と空間の扉”與之不同,只可以從Ai到Bi。事實上,由於牧師妹醬的墨鏡黨(看看我的頭像就知道了)的不斷幹擾使得連結非常不穩定。牧師妹醬的墨鏡黨的幹擾如下:如果有一條“時間と空間の扉”可以從Ai到Bi,那麼保證不可能通過一些道路和“時間と空間の扉”從Bi回到Ai。所以有些地區可能無法到達,需要揚帆遠洋對自己進行Teleport才可以。
揚帆遠洋現在呆在S城鎮,由於他需要把每個“れいじまいご·ベクトル変換”的裝置調整完畢,因此揚帆遠洋寫了一個程式計算從S出發,對於每個地區而言計算出了最小的花費,如果不可能,則輸出“Need Teleport To Repair”。最後輸出,一共有多少個地方是需要用Teleport的。
但是由於墨鏡黨不斷的搗亂,這個程式現在無法工作,請你複述出來這個程式。
輸入描述 Input Description
第1行有四個空格隔開的整數T、R、P和S。
第2至R+1行每行有3個空格隔開的正整數,表示一條道路的Ai、Bi和Ci。
第R+2至R+P+1行每行有3個空格隔開的正整數,表示一條“時間と空間の扉”的Ai、Bi和Ci。
輸出描述 Output Description
第1到T行每行輸出的是從S到達地區i的最小花費,如果不存在輸出“Need Teleport To Repair”(沒有引號)。
最後一行為一共有多少個地方是需要用Teleport的。
範例輸入 Sample Input
6 3 3 4
1 2 5
3 4 5
5 6 10
3 5 -100
4 6 -100
1 3 -10
範例輸出 Sample Output
Need Teleport To Repair
Need Teleport To Repair
5
0
-95
-100
2
資料範圍及提示 Data Size & Hint
1≤T≤25000,1≤R≤50000,1≤P≤50000,1≤S≤T
1≤Ai≤T,1≤Bi≤T,-10000≤Ci≤10000(對於“時間と空間の扉”來說花費才可能是負數)
說點題外話…剛才看了看其他同學們的部落格,感覺他們寫的好用心啊QAQ,然而自己懶到不行,不想寫部落格…過兩天去了北京有時間的話就把這段時間做的題都好好整理一下吧…
其實在TLE的下面還有一次WA…因為我還以為不用輸出自己到自己的距離,也沒有好好看範例就交了…mdzz…
第一次TLE是裸的spfa就交了,第二次是加了手動讀入的,第三次就是手動讀入+spfa slf最佳化了,這速度簡直吊的飛起…
這個題沒什麼思想上的難度,不加手動讀入的spfa的最佳化就可過,這居然是個大師題…害怕。
代碼如下:
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int MAX_V=25000+10;const int MAX_E=100000+10;int tot;int first[MAX_V],nxt[MAX_E<<1],d[MAX_V];struct edge{ int from,to,cost;}es[MAX_E<<1];void read(int &a){ a=0; int h=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') h=-1; c=getchar(); } while(c>='0'&&c<='9') { a*=10; a+=c-'0'; c=getchar(); } a*=h;}void init(){ memset(first,-1,sizeof(first)); memset(d,0x3f,sizeof(d)); tot=0;}void build(int ff,int tt,int dd){ es[++tot]=(edge){ff,tt,dd}; nxt[tot]=first[ff]; first[ff]=tot;}bool vis[MAX_V];deque<int>q;void spfa(int s){ d[s]=0; vis[s]=1; q.push_front(s); while(!q.empty()) { int u=q.front(); q.pop_front(); vis[u]=0; for(int i=first[u];i!=-1;i=nxt[i]) { int v=es[i].to; if(d[v]>d[u]+es[i].cost) { d[v]=d[u]+es[i].cost; if(!vis[v]) { vis[v]=1; if(q.empty()) q.push_front(v); else if(d[v]>d[q.front()]) q.push_back(v); else q.push_front(v); } } } }}int main(){ init(); int V,E,Pe,Ts; read(V),read(E),read(Pe),read(Ts); for(int i=1;i<=E;i++) { int ff,tt,dd; read(ff),read(tt),read(dd); build(ff,tt,dd); build(tt,ff,dd); } for(int i=1;i<=Pe;i++) { int ff,tt,dd; read(ff),read(tt),read(dd); build(ff,tt,dd); } int cnt=0; spfa(Ts); for(int i=1;i<=V;i++) { if(d[i]==0x3f3f3f3f) { puts("Need Teleport To Repair"); cnt++; } else printf("%d\n",d[i]); } printf("%d\n",cnt); return 0;}