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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CJOJ 免费航班

發布時間:2023/12/2 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CJOJ 免费航班 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

小Z在MOI比賽中獲得了大獎,獎品是一張特殊的機 票。使用這張機票,可以在任意一個國家內的任意城市之間的免費飛行,只有跨國飛行時才會有額外的費用。小Z獲得了一張地圖,地圖上有城市之間的飛機航班和 費用。已知從每個城市出發能到達所有城市,兩個城市之間可能有不止一個航班。一個國家內的每兩個城市之間一定有不止一條飛行路線,而兩個國家的城市之間只 有一條飛行路線。小Z想知道,從每個城市出發到額外費用最大的城市,以便估算出出行的費用,請你幫助他。當然,你不能通過乘坐多次一個航班增加額外費用, 也就是必須沿費用最少的路線飛行。

Input

第一行,兩個整數N,M,表示地圖上有N個城市,M條航線。
接下來M行,每行三個整數a,b,c,表示城市a,b之間有一條費用為c的航線。

Output

共N行,第i行為從城市i出發到達每個城市額外費用的最大值。

Sample Input

6 6
1 4 2
1 2 6
2 5 3
2 3 7
6 3 4
3 1 8

Sample Output

4
4
4
6
7
7

Hint

樣例說明
有四個國家,包含的城市分別為 {1,2,3},{4},{5},{6}。從城市1出發到達城市6,乘坐(1,3)(3,6)兩個航班費用最大,(1,3)在國內為免費航班,(3,6)的費用為4,所以從1出發的最大費用為4。

數據規模
對于30%的數據 1<=N<=1000,1<=M<=1000
對于100%的數據 1<=N<=20000,1<=M<=200000

Source

動態規劃 ,連通性

?

根據題目描述,每個國家是一個邊雙連通分量,把每個邊雙連通分量縮點后,原圖變為一棵樹.

相當于是求樹上每個點在樹上的最長路.

所有點的樹上最長路可以通過兩邊dfs進行DP;

第一遍:求出每個點只到他子樹內部的最長路和次長路

第二遍:每個點再由他父親來更新往改點的子樹外走的最長路,因為該點到子樹外面的路必經過他爸爸

具體實現就是最長路和次長路轉化,轉移畫畫圖就好了

邊雙連通縮點的話就是把橋標記后在dfs一遍

#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<vector> #define RG register using namespace std; typedef long long ll; const int N=20050; int gi(){int x=0;char ch=getchar();while(ch<'0'||ch>'9') ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x; } int head[N],nxt[N*20],to[N*20],dfn[N],low[N],vis[N],zhan[N],w[N*20],cnt=1,tot,sum,top,pd[N*20]; vector<int>q[N],p[N],W[N]; int dis[N][2],vis2[N],fr[N]; void tarjan(int x,int fa){dfn[x]=low[x]=++sum;for(RG int i=head[x];i;i=nxt[i]){int y=to[i];if(!dfn[y]){tarjan(y,x);low[x]=min(low[x],low[y]);if(low[y]>dfn[x]) pd[i]=pd[i^1]=1;}else if(y!=fa) low[x]=min(low[x],dfn[y]);} } void dfs3(int x,int gg){fr[x]=gg,vis[x]=1;q[gg].push_back(x);for(RG int i=head[x];i;i=nxt[i]){if(!pd[i]&&!vis[to[i]]) dfs3(to[i],tot);} } void dfs1(int x){vis2[x]=1;for(RG int i=0;i<p[x].size();i++){int y=p[x][i],w=W[x][i];if(!vis2[y]){dfs1(y);if(dis[y][1]+w>=dis[x][1]){dis[x][0]=dis[x][1];dis[x][1]=dis[y][1]+w;}else dis[x][0]=max(dis[x][0],dis[y][1]+w);}} } void dfs2(int x){vis2[x]=1;for(RG int i=0;i<p[x].size();i++){int y=p[x][i],w=W[x][i];if(!vis2[y]){if(dis[y][1]+w==dis[x][1]){dis[y][0]=max(dis[y][0],min(dis[x][1]-w,dis[x][0]+w));dis[y][1]=max(dis[x][1]-w,dis[x][0]+w);}else{dis[y][0]=max(dis[y][0],max(dis[x][0]+w,min(dis[y][1],dis[x][1]+w)));dis[y][1]=max(dis[y][1],dis[x][1]+w);}dfs2(y);}} } int main(){int n,m,x,w1,y;cnt=1;n=gi(),m=gi();for(RG int i=1;i<=m;i++){x=gi(),y=gi(),w1=gi();to[++cnt]=y,w[cnt]=w1,nxt[cnt]=head[x],head[x]=cnt;to[++cnt]=x,w[cnt]=w1,nxt[cnt]=head[y],head[y]=cnt;}tarjan(1,1);for(int i=1;i<=n;i++) if(!vis[i]) dfs3(i,++tot);for(RG int i=1;i<=tot;i++)for(RG int j=0;j<q[i].size();j++)for(RG int k=head[q[i][j]];k;k=nxt[k]){int y=fr[to[k]],w1=w[k];if(y!=i){p[i].push_back(y);W[i].push_back(w1);}}dfs1(1);for(RG int i=1;i<=tot;i++) vis2[i]=0;dfs2(1);for(RG int i=1;i<=n;i++) printf("%d\n",dis[fr[i]][1]);return 0; }

?

轉載于:https://www.cnblogs.com/qt666/p/6880132.html

總結

以上是生活随笔為你收集整理的CJOJ 免费航班的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。