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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

bzoj2753: [SCOI2012]滑雪与时间胶囊

發布時間:2024/9/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj2753: [SCOI2012]滑雪与时间胶囊 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

bfs+最小樹形圖+kruskal算法。

最小樹形圖形象地來說就是有向圖的最小生成樹,這個不能拿kruskal算法或者是prim算法直接求,否則會錯。

就是w[u][v]!=w[v][u]的情況。

而這道題用朱劉算法肯定是行不通的。

但是這道題的有向邊并不是邊的性質,而是點的高度決定的。這樣我們就可以分層求最小生成樹。

如果加進高度為h的點,只需用kruskal算法選最短的邊就可以了,而且不會影響到后面的選擇。

于是我們把kruskal算法的排序改成以結尾點高度為第一關鍵字降序和邊長度為第二關鍵字升序排序。。。(意會,要不看cmp,嗯。)

這樣就可以辣。

#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 100000 + 10; const int maxm = 2000000 + 10;int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f; }struct Edge {int u,v,d; }e[maxm];int h[maxn],f[maxn]; int g[maxn],v[maxm],next[maxm],eid; int res1,n,m; long long res2; bool vis[maxn]; int q[maxm],l,r,u;void addedge(int a,int b) {v[eid]=b; next[eid]=g[a]; g[a]=eid++; }bool cmp(Edge a,Edge b) {if(h[a.v]!=h[b.v]) return h[a.v]>h[b.v];return a.d<b.d; }int find(int x) {return f[x]==x?x:f[x]=find(f[x]); } int main() {memset(g,-1,sizeof(g));n=read(); m=read();for(int i=1;i<=n;i++) h[i]=read();for(int i=1,u,v;i<=m;i++) { u=read(); v=read(); e[i].d=read();if(h[u]>=h[v]) addedge(u,v);if(h[v]>=h[u]) {addedge(v,u); swap(u,v);}e[i].u=u; e[i].v=v;}sort(e+1,e+m+1,cmp);vis[q[r++]=1]=1,res1=1;while(l<r) {u=q[l++];for(int i=g[u];~i;i=next[i]) if(!vis[v[i]]) {vis[q[r++]=v[i]]=1;res1++;}}for(int i=1;i<=n;i++) f[i]=i;for(int i=1,ru,rv;i<=m;i++) if(vis[e[i].u]&&vis[e[i].v]) {ru=find(e[i].u);rv=find(e[i].v);if(ru!=rv) {res2+=e[i].d;f[rv]=ru;}}printf("%d %lld\n",res1,res2);return 0; }

轉載于:https://www.cnblogs.com/invoid/p/5635995.html

總結

以上是生活随笔為你收集整理的bzoj2753: [SCOI2012]滑雪与时间胶囊的全部內容,希望文章能夠幫你解決所遇到的問題。

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