Background
在一個遙遠的世界裏有兩個國家:位於大陸西端的傑森國和位於大陸東端的克里斯國。兩個國家的人民分別信仰兩個對立的神:傑森國信仰象徵黑暗和毀滅的神曾·布拉澤,而克里斯國信仰象徵光明和永恆的神斯普林·布拉澤。ios
幻想歷8012年1月,傑森國正式宣佈曾·布拉澤是他們惟一信仰的神,同時開始迫害在傑森國的信仰斯普林·布拉澤的克里斯國教徒。git
幻想歷8012年3月2日,位於傑森國東部小鎮神諭鎮的克里斯國教徒發動起義。數組
幻想歷8012年3月7日,神諭鎮的起義被傑森國大軍以殘酷手段鎮壓。ui
幻想歷8012年3月8日,克里斯國對傑森國宣戰。由數十萬大軍組成的克里斯軍團開至兩國邊境,與傑森軍團對峙。spa
幻想歷8012年4月,克里斯軍團攻破傑森軍團防線進入神諭鎮,該鎮倖存的克里斯國教徒獲得解放。code
戰爭隨後進入膠着狀態,曠日持久。戰況慘烈,一時間槍林彈雨,硝煙瀰漫,民不聊生。ip
Description
幻想歷8012年5月12日深夜,斯普林·布拉澤降下神諭:「Trust me, earn eternal life.」克里斯軍團士氣大增。做爲克里斯軍團的主帥,你決定利用這一機會發動奇襲,一舉擊敗傑森國。具體地說,傑森國有N個城市,由M條單向道路鏈接。神諭鎮是城市1而傑森國的首都是城市N。你只需摧毀位於傑森國首都的曾·布拉澤大神殿,傑森國的信仰,軍隊還有一切就都會土崩瓦解,灰飛煙滅。get
爲了儘可能減少己方的消耗,你決定使用自爆機器人完成這一任務。惟一的困難是,傑森國的一部分城市有結界保護,不破壞掉結界就沒法進入城市。而每一個城市的結界都是由分佈在其餘城市中的一些結界發生器維持的,若是想進入某個城市,你就必須破壞掉維持這個城市結界的全部結界發生器。input
如今你有無限多的自爆機器人,一旦進入了某個城市,自爆機器人能夠瞬間引爆,破壞一個目標(結界發生器,或是傑森國大神殿),固然機器人自己也會一塊兒被破壞。你須要知道:摧毀傑森國所需的最短期。it
Input
輸入文件的landcraft.in的第一行兩個正整數N, M。
接下來M行,每行三個正整數ui, vi, wi,表示有一條從城市ui到城市vi的單向道路,自爆機器人經過這條道路須要wi的時間。
以後N行,每行描述一個城市。首先是一個正整數li,維持這個城市結界所使用的結界發生器數目。以後li個1~N之間的城市編號,表示每一個結界發生器的位置。若是li = 0,則說明該城市沒有結界保護,保證l1 = 0 。
Output
輸出文件landcraft.out僅包含一個正整數 ,擊敗傑森國所需的最短期。
最短路問題,結果由於數組開小改了很久???
記錄\(dis[x]\)表明到達\(x\)的最短期。
記錄\(real[x]\)表明到達\(x\)的實際時間。
對於每個點,咱們去更新其相連節點的時候要用\(max(dis[x],real[x])\)去更新。
而後注意創建結界保護的邊的時候建\(li\)到\(i\)的有向邊。
由於我搞不清因此直接建雙向邊
而後最後輸出答案輸出\(max(dis[n],real[n])\)便可。
代碼
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #define R register using namespace std; const int gz=5e4+8; inline void in(R int &x) { R int f=1;x=0;char s=getchar(); while(!isdigit(s)){if(s=='-')f=-1;s=getchar();} while(isdigit(s)){x=x*10+s-'0';s=getchar();} x*=f; } int head[gz],tot,pr[gz],cnt,hd[gz]; struct cod{int u,v,w;}edge[gz<<1],e[gz<<1]; inline void add(R int x,R int y,R int z) { edge[++tot].u=head[x]; edge[tot].v=y; edge[tot].w=z; head[x]=tot; } inline void ado(R int x,R int y) { e[++cnt].u=pr[x]; e[cnt].v=y; pr[x]=cnt; } int dis[gz],real[gz],n,m; bool vis[gz]; struct hop { int u,d; bool operator <(const hop&a)const { return d>a.d; }; }; inline void dij() { for(R int i=1;i<=n;i++)dis[i]=2147483644; priority_queue<hop>q;dis[1]=real[1]=0; q.push((hop){1,0}); while(!q.empty()) { R int u=q.top().u;q.pop(); if(vis[u])continue; vis[u]=true; R int now=max(dis[u],real[u]); for(R int i=head[u];i;i=edge[i].u) { if(dis[edge[i].v]>now+edge[i].w) { dis[edge[i].v]=now+edge[i].w; if(hd[edge[i].v]==0) q.push((hop){edge[i].v,max(dis[edge[i].v],real[edge[i].v])}); } } for(R int i=pr[u];i;i=e[i].u) { hd[e[i].v]--; real[e[i].v]=max(real[e[i].v],now); if(hd[e[i].v]==0) q.push((hop){e[i].v,max(real[e[i].v],dis[e[i].v])}); } } printf("%d\n",max(real[n],dis[n])); } int main() { in(n),in(m); for(R int i=1,x,y,z;i<=m;i++) { in(x),in(y),in(z); if(x==y)continue; add(x,y,z); } for(R int i=1,x;i<=n;i++) { in(x);hd[i]=x; for(R int fk;x;x--) in(fk),ado(fk,i),ado(i,fk); } dij(); }