4919: [Usaco2009 Jan]Telephone Lines
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 5 Solved: 3
[Submit][Status][Web Board]
Description
在郊区有N座通信基站,P条双向电缆,第 i 条电缆连接基站 A_i 和 B_i。特别地,1号基站是通信公司的总站,N
号基站位于一座农场中。现在,农场主希望对通信线路进行升级,其中升级第 i 条电缆需要花费 L_i。电话公司
正在举行优惠活动。农场主可以指定一条从1号基站到N号基站的路径,并指定路径上不超过K条电缆,由电话公司
免费提供升级服务。农场主只需要支付在该路径上剩余的电缆中,升级价格最贵的那条电缆的花费即可。求至少用
多少钱能完成升级。
0≤K<N≤1000,1≤P≤10000。
号基站位于一座农场中。现在,农场主希望对通信线路进行升级,其中升级第 i 条电缆需要花费 L_i。电话公司
正在举行优惠活动。农场主可以指定一条从1号基站到N号基站的路径,并指定路径上不超过K条电缆,由电话公司
免费提供升级服务。农场主只需要支付在该路径上剩余的电缆中,升级价格最贵的那条电缆的花费即可。求至少用
多少钱能完成升级。
0≤K<N≤1000,1≤P≤10000。
Input
Output
HINT
Source
求k+1大边的最大值最小
最短路+二分
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> using namespace std; struct my{ int v; int next; int w; }; const int maxn=1000+10; const int nil=(1<<29); int n,fa,m,k,fa2; int d[maxn],vis[maxn]; int adj[maxn]; int adj2[maxn]; my bian2[maxn*20]; my bian[maxn*20]; void myinsert(int u,int v,int w){ bian[++fa].v=v; bian[fa].w=w; bian[fa].next=adj[u]; adj[u]=fa; } void myinsert2(int u,int v,int w){ bian2[++fa2].v=v; bian2[fa2].w=w; bian2[fa2].next=adj2[u]; adj2[u]=fa2; } bool spfa(int x){ queue<int>q; memset(vis,false,sizeof(vis)); for (int i=1;i<=n;i++) d[i]=nil; d[x]=0; q.push(x); vis[x]=true; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=false; for (int i=adj[u];i;i=bian[i].next){ int v=bian[i].v; if(d[u]<nil&&d[v]>d[u]+bian[i].w){ d[v]=d[u]+bian[i].w; if(!vis[v]){ vis[v]=true; q.push(v); } } } } return d[n]<=k; } bool check(int p){ for (int i=1;i<=n;i++){ for (int j=adj2[i];j;j=bian2[j].next){ if(bian2[j].w<=p) bian[j].w=0; else bian[j].w=1; } } return spfa(1); } int main(){ int ans=-1,l=0,r=0; int u,v,w; scanf("%d%d%d",&n,&m,&k); fa=0; fa2=0; for (int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); myinsert(u,v,w); myinsert(v,u,w); myinsert2(u,v,w); myinsert2(v,u,w); r=max(w,r); } while(l<=r){ int mid=(l+r)/2; if(check(mid)){ ans=mid; r=mid-1; } else { l=mid+1; } } printf("%d ",ans); return 0; }