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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

[Usaco2007 Jan]Telephone Lines架设电话线

發(fā)布時間:2024/4/14 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Usaco2007 Jan]Telephone Lines架设电话线 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目描述

FarmerJohn打算將電話線引到自己的農(nóng)場,但電信公司并不打算為他提供免費(fèi)服務(wù)。于是,FJ必須為此向電信公司支付一定的費(fèi)用。FJ的農(nóng)場周圍分布著N(1<=N<=1,000)根按1..N順次編號的廢棄的電話線桿,任意兩根電話線桿間都沒有電話線相連。一共P(1<=P<=10,000)對電話線桿間可以拉電話線,其余的那些由于隔得太遠(yuǎn)而無法被連接。第i對電話線桿的兩個端點(diǎn)分別為A_i、B_i,它們間的距離為L_i(1<=L_i<=1,000,000)。數(shù)據(jù)中保證每對{A_i,B_i}最多只出現(xiàn)1次。編號為1的電話線桿已經(jīng)接入了全國的電話網(wǎng)絡(luò),整個農(nóng)場的電話線全都連到了編號為N的電話線桿上。也就是說,FJ的任務(wù)僅僅是找一條將1號和N號電話線桿連起來的路徑,其余的電話線桿并不一定要連入電話網(wǎng)絡(luò)。經(jīng)過談判,電信公司最終同意免費(fèi)為FJ連結(jié)K(0<=K<N)對由FJ指定的電話線桿。對于此外的那些電話線,FJ需要為它們付的費(fèi)用,等于其中最長的電話線的長度(每根電話線僅連結(jié)一對電話線桿)。如果需要連結(jié)的電話線桿不超過K對,那么FJ的總支出為0。請你計算一下,FJ最少需要在電話線上花多少錢。

輸入格式

第1行: 3個用空格隔開的整數(shù):N,P,以及K

第2..P+1行: 第i+1行為3個用空格隔開的整數(shù):A_i,B_i,L_i

輸出格式

第1行: 輸出1個整數(shù),為FJ在這項工程上的最小支出。

如果任務(wù)不可能完成, 輸出-1


容易想到的策略是:把1~n路徑上花費(fèi)最高的k條路徑去掉。所以我們可以枚舉每條路徑并枚舉路徑上的每條邊來解答。但這顯然不是我們能夠接受的復(fù)雜度。

我們需要換一種思路來做。我們來分析一下答案的性質(zhì):

設(shè)答案為ans,那么在1~n的所有路徑中l(wèi)enth<=ans的都可以免費(fèi),其余的計入k條免費(fèi)線路中。如果ans過小,那么lenth>ans的路徑數(shù)可能大于k,如果過大則得不到最優(yōu)解。所以我們可以二分答案,對于每個二分出的limitation,把邊長大于它的路線的代價改成1,其余的代價為0。然后跑一遍最短路,看最短路長度是否≤k即可。

最短路可以用Dijkstra+Heap做到O((N+M) * logN),二分答案的復(fù)雜度為O(logAns),所以總復(fù)雜度為:

\[ O((N+M)logNlogAns) \]

可以通過本題。

#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<queue> #define maxn 1001 #define maxm 10001 using namespace std;struct edge{int to,next,dis;edge(){}edge(const int &_to,const int &_dis,const int _next){to=_to,dis=_dis,next=_next;} }e[maxm<<1]; int head[maxn],k;int dis[maxn],maxlen,ans; bool vis[maxn]; int n,m,t; priority_queue< pair<int,int>,vector< pair<int,int> >,greater< pair<int,int> > > q;inline int read(){register int x(0),f(1); register char c(getchar());while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f; } inline void add(const int &u,const int &v,const int &w){e[k]=edge(v,w,head[u]);head[u]=k++; }inline void dijkstra(const int &lim){memset(dis,0x3f,sizeof dis);memset(vis,false,sizeof vis);q.push(make_pair(0,1));dis[1]=0;while(q.size()){int u=q.top().second; q.pop();if(vis[u]) continue; vis[u]=true;for(register int i=head[u];~i;i=e[i].next){int v=e[i].to;if(dis[v]>dis[u]+(e[i].dis>lim))dis[v]=dis[u]+(e[i].dis>lim),q.push(make_pair(dis[v],v));}} }int main(){memset(head,-1,sizeof head);n=read(),m=read(),t=read();for(register int i=1;i<=m;i++){int u=read(),v=read(),w=read();add(u,v,w),add(v,u,w);if(maxlen<w) maxlen=w;}int l=0,r=maxlen,flag=false;while(l<=r){int lim=l+r>>1;dijkstra(lim);if(dis[n]<=t) flag=true,ans=lim,r=lim-1;else l=lim+1;}printf("%d\n",flag?ans:-1);return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/akura/p/10848893.html

總結(jié)

以上是生活随笔為你收集整理的[Usaco2007 Jan]Telephone Lines架设电话线的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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