日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2019ICPC(银川) - Delivery Route(强连通缩点+分块最短路)

發(fā)布時間:2024/4/11 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019ICPC(银川) - Delivery Route(强连通缩点+分块最短路) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出n個點和m條邊構(gòu)成的圖,每條邊都有權(quán)值,其中m1條邊是雙向的,且權(quán)值非負,有m2條邊是單向的,且權(quán)值可負,現(xiàn)在要求從給定起點st到其他每個點的最短路,若不存在路徑則輸出NO PATH

題目分析:看似很簡單的單源最短路的題目,因為存在了負邊權(quán)導(dǎo)致無法直接用迪杰斯特拉解決,又因為這個題目的數(shù)據(jù)經(jīng)過了特殊構(gòu)造,所以SPFA也會超時,只能另想辦法解決

這個題目的特點是,所有的雙向邊都是非負的,可以用迪杰斯特拉計算最短路,這也引導(dǎo)我們將整個圖分塊,分為一塊一塊的整體,這一步操作可以用tarjan強連通縮點來解決,又因為題目保證有向邊不會構(gòu)成環(huán),這樣在縮點后的新圖就是一個有向無環(huán)圖,一看到有向無環(huán)圖就要想拓撲排序,很顯然縮點后的新圖的最短路可以用拓撲排序來O(n)計算,時間復(fù)雜度大概是O(dijkstra)+O(topo),因為是加法關(guān)系,所以可以在題目規(guī)定的范圍內(nèi)解決

下面列出幾個小細節(jié),需要注意一下:

  • 強連通縮點只縮與起點st有關(guān)系的點即可,其他不相連的點答案肯定是NO PATH
  • 縮點后建新圖要記得去掉重邊,目的是為了方便記錄入度進行拓撲排序
  • 每個連通塊都有不同的起點,也就是連接上一個連通塊與當(dāng)前聯(lián)通塊的邊
  • 迪杰斯特拉的最短路僅限于在每個連通塊內(nèi)部進行,而連通塊間的傳遞用拓撲實時更新每個連通塊起點的最小值即可
  • 多說無益,還是直接看代碼吧

    代碼:

    #include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=25000+100;const int M=150000+100;struct Egde {int to,next,w; }edge1[M],edge2[M];int head1[N],head2[N],low[N],dfn[N],c[N],Stack[N],d[N],in[N],num,cnt,cnt2,cnt1,dcc,n,top;bool ins[N],vis[N];vector<int>scc[N],start[N];//scc:強連通分塊 start:每個分塊的迪杰斯特拉的起點 vector<pair<int,int>>node;//node:新圖的邊(需要去重)queue<int>q;//儲存每個聯(lián)通塊的起點用于跑迪杰斯特拉void addedge1(int u,int v,int w) {edge1[cnt1].w=w;edge1[cnt1].to=v;edge1[cnt1].next=head1[u];head1[u]=cnt1++; }void addedge2(int u,int v,int w=0) {edge2[cnt2].w=w;edge2[cnt2].to=v;edge2[cnt2].next=head2[u];head2[u]=cnt2++; }void tarjan(int u) {dfn[u]=low[u]=++num;Stack[++top]=u;ins[u]=true;for(int i=head1[u];i!=-1;i=edge1[i].next){int v=edge1[i].to;if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(ins[v])low[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){cnt++;int v;do{v=Stack[top--];ins[v]=false;c[v]=cnt;scc[cnt].push_back(v);}while(u!=v);} }void build(int st)//縮點+連邊 {tarjan(st);//注意這里,只對st縮點即可for(int i=1;i<=n;i++)//遍歷每一條邊{for(int j=head1[i];j!=-1;j=edge1[j].next){int u=i;int v=edge1[j].to;if(c[u]!=c[v]&&c[u]&&c[v])//如果這條邊的兩個端點與st相通且不在同一個連通塊中{node.push_back(make_pair(c[u],c[v]));//記錄該邊為新圖的邊start[c[v]].push_back(v);//記錄哪些點可以作為該區(qū)塊的起點 }}}sort(node.begin(),node.end());//去掉重邊 node.erase(unique(node.begin(),node.end()),node.end());for(int i=0;i<node.size();i++)//重新建邊 {addedge2(node[i].first,node[i].second);in[node[i].second]++;//記錄入度} }struct Node {int to,w;Node(int TO,int W){to=TO;w=W;}bool operator<(const Node& a)const{return w>a.w;} };void Dijkstra(int st)//迪杰斯特拉 {priority_queue<Node>q;q.push(Node(st,d[st]));memset(vis,false,sizeof(vis));while(q.size()){Node cur=q.top();int u=cur.to;q.pop();if(vis[u])continue;vis[u]=true;for(int i=head1[u];i!=-1;i=edge1[i].next)//掃描出所有邊 {int v=edge1[i].to;int w=edge1[i].w;if(c[v]!=c[u])//不在同一個連通塊 continue;if(d[v]>d[u]+w)//更新 {d[v]=d[u]+w;q.push(Node(v,d[v]));}}} }void update(int x)//x為連通塊 {for(int i=0;i<scc[x].size();i++)//掃描出當(dāng)前聯(lián)通塊的所有點 {int u=scc[x][i];for(int j=head1[u];j!=-1;j=edge1[j].next)//掃描出所有與其他聯(lián)通塊相連的點{int v=edge1[j].to;int w=edge1[j].w;if(c[v]!=c[u])d[v]=min(d[v],d[u]+w);//拓撲更新最短路}}for(int i=head2[x];i!=-1;i=edge2[i].next)//拓撲掃描所有連通塊{int y=edge2[i].to;in[y]--;if(in[y]==0){for(int j=0;j<start[y].size();j++)//拓撲排序找到下一個連通塊的起點,加入隊列q.push(start[y][j]);}} }void init() {while(q.size())q.pop();for(int i=0;i<N;i++){scc[i].clear();start[i].clear();}node.clear();top=cnt=cnt1=cnt2=num=dcc=0;memset(head2,-1,sizeof(head2));memset(head1,-1,sizeof(head1));memset(low,0,sizeof(low));memset(dfn,0,sizeof(dfn));memset(c,0,sizeof(c));memset(ins,false,sizeof(ins));memset(in,0,sizeof(in));memset(d,inf,sizeof(d)); }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);init();int m1,m2,st;scanf("%d%d%d%d",&n,&m1,&m2,&st);while(m1--){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge1(u,v,w);addedge1(v,u,w);}while(m2--){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge1(u,v,w);}build(st);q.push(st);d[st]=0;while(q.size()){int u=q.front();q.pop();Dijkstra(u);if(q.empty()||c[q.front()]!=c[u])//如果已經(jīng)處理完當(dāng)前連通塊,嘗試尋找下一個連通塊update(c[u]);}for(int i=1;i<=n;i++){if(d[i]==inf)puts("NO PATH");elseprintf("%d\n",d[i]);}return 0; }

    ?

    總結(jié)

    以上是生活随笔為你收集整理的2019ICPC(银川) - Delivery Route(强连通缩点+分块最短路)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 四虎在线看片 | 挪威xxxx性hd极品 | 午夜不卡在线观看 | 国产内射一区二区 | avtt男人天堂 | 狠狠干免费视频 | 女人叉开腿让男人桶 | 18精品爽国产白嫩精品 | 日韩二区三区 | 日韩中文字幕av在线 | 性久久久久久久久久 | 欧美激情一区二区在线 | 无码人妻精品一区二区三区温州 | 一本色道久久综合熟妇 | 日韩国产精品久久 | 亚洲卡一| 3d动漫精品啪啪一区二区竹菊 | 成人av社区 | 97精品人妻一区二区三区香蕉 | 丰满大乳露双乳呻吟 | 超碰免费看| 天天操夜夜骑 | 国产精品久久久久毛片大屁完整版 | 欧美嫩交 | 884aa四虎影成人精品一区 | 啪网址 | 亚色在线观看 | 一区二区免费播放 | 嫩草99 | 最近更新中文字幕 | 99av国产精品欲麻豆 | 99爱精品 | 日本女教师电影 | 精品一区二区毛片 | 深夜老司机福利 | 国产一级大片在线观看 | 国产www性| 国产精彩视频在线观看 | 99天堂网| 精品国产乱码一区二区三 | 亚洲免费影院 | 久久免费视频网 | 日本我不卡 | 黑人巨大av | 天天免费看av | 亚洲免费成人 | 97精品人妻一区二区三区在线 | 色婷婷av一区二区 | 亚洲va天堂va欧美ⅴa在线 | 亚洲aaaaaaa| 精品人妻人人做人人爽夜夜爽 | 日韩在线视频在线观看 | 亚洲国产精选 | 国产情侣露脸自拍 | 一区二区三区四区在线播放 | 久久波多野| 玩偶游戏在线观看免费 | 免费观看黄色小视频 | 香蕉传媒 | av网站免费在线播放 | 午夜电影天堂 | 精品一区二区三区成人免费视频 | 人人妻人人澡人人爽欧美一区 | 日本69少妇 | 高清日韩 | 日日嗨av一区二区三区四区 | 国产一区2 | 亚洲国产精品成人va在线观看 | 久久97精品久久久久久久不卡 | 亚洲一区二区三区香蕉 | 婷婷六月激情 | 亚洲精品黄 | 午夜婷婷网 | 淫片在线| 台湾av在线 | 操丰满女人 | 亚洲一区二区蜜桃 | 欧美日韩一区二区三区在线 | 久久这里只有精品首页 | 欧美日韩免费在线 | 樱花视频在线免费观看 | 播播开心激情网 | 欧美性爱视频久久 | 国产午夜精品久久久 | 91麻豆成人精品国产免费网站 | 国产天天综合 | 亚洲伦理影院 | 一区二区三区视频观看 | 97公开视频| 99精品国产成人一区二区 | av色在线 | 国产av一区二区不卡 | 另一种灿烂生活 | 久久久久久久人妻无码中文字幕爆 | 男女操操 | 亚洲一区欧洲一区 | 欧美无马 | 一区成人 | 色狠狠一区二区三区 |