luogu P5304 [GXOI/GZOI2019]旅行者
生活随笔
收集整理的這篇文章主要介紹了
luogu P5304 [GXOI/GZOI2019]旅行者
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
所以這個\(5s\)是SMG
暴力是枚舉每一個點跑最短路,然后有一個很拿衣服幼稚的想法,就是把所有給出的關鍵點當出發點,都丟到隊列里,求最短路的時候如果當前點\(x\)某個相鄰的點\(y\)是關鍵點,就用\(dis_x+\)邊權\(w_i\)更新答案.感覺這個復雜度是正確的,然后跑一下樣例也對
交上去就可以獲得70'的好成績
這個方法會有一種特殊情況無法處理,就是這條路徑的起點和終點都是同一點,因為圖中可能有環.那么我們更新答案就不能用起點是\(y\)的路徑更新答案,于是考慮同時記錄從某個出發點到一個點的最短路以及是從哪個出發點轉移過來的,同時求次短路,要求最短路的起點和次短路起點不一樣,那么在更新答案時,如果最短路起點不等于終點就用最短路更新,否則用次短路
// luogu-judger-enable-o2 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector> #include<cmath> #include<ctime> #include<queue> #include<map> #include<set> #define LL long long #define db doubleusing namespace std; const int N=100000+10,M=500000+10; int rd() {int x=0,w=1;char ch=0;while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}return x*w; } int to[M],nt[M],hd[N],tot; LL w[M]; void add(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;} bool v[N]; struct nn {LL d;int y;void clr(){d=1ll<<50,y=0;}bool operator < (const nn &bb) const {return d<bb.d;} }d1[N],d2[N]; struct node {int x;nn d1,d2;bool operator < (const node &bb) const {return bb.d1.d!=d1.d?bb.d1<d1:bb.d2<d2;} }; priority_queue<node> q; int n,m,kk;int main() {int T=rd();while(T--){memset(hd,0,sizeof(hd)),tot=0;n=rd(),m=rd(),kk=rd();for(int i=1;i<=m;++i){int x=rd(),y=rd(),z=rd();if(x==y) continue;add(x,y,z);}memset(v,0,sizeof(v));for(int i=1;i<=n;++i) d1[i].clr(),d2[i].clr();LL ans=1ll<<50;while(kk--){int x=rd();d1[x]=(nn){0,x},v[x]=1,q.push((node){x,d1[x],d2[x]});}while(!q.empty()){int x=q.top().x;nn dd1=q.top().d1,dd2=q.top().d2;q.pop();if(d1[x]<dd1||d2[x]<dd2) continue;for(int i=hd[x];i;i=nt[i]){int y=to[i];if(v[y]){if(dd1.y!=y) ans=min(ans,dd1.d+w[i]);else ans=min(ans,dd2.d+w[i]);}else{nn n1=d1[y],n2=d2[y];if(n1.d>dd2.d+w[i]){if(n1.y!=n2.y) n2=n1;n1=(nn){dd2.d+w[i],dd2.y};}else if(n2.d>dd2.d+w[i]&&n1.y!=dd2.y) n2=(nn){dd2.d+w[i],dd2.y};if(n1.d>dd1.d+w[i]){if(n1.y!=n2.y) n2=n1;n1=(nn){dd1.d+w[i],dd1.y};}else if(n2.d>dd1.d+w[i]&&n1.y!=dd1.y) n2=(nn){dd1.d+w[i],dd1.y};if(n1<d1[y]||n2<d2[y]) q.push((node){y,d1[y]=n1,d2[y]=n2});}}}printf("%lld\n",ans);}return 0; }轉載于:https://www.cnblogs.com/smyjr/p/10763331.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的luogu P5304 [GXOI/GZOI2019]旅行者的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 4万次下载,我的这本电子书连续数月蝉联阿
- 下一篇: ucml选项卡