bzoj1614[Usaco2007 Jan]Telephone Lines架设电话线*

bzoj1614[Usaco2007 Jan]Telephone Lines架设电话线

题意:

n个节点,1号节点已经连入互联网,现在需要将整个图连入网络。有K条边可以免费连接,最后总费用为所有连边费用的最大值,求最小总费用。n≤10000

题解:

二分费用,将连边费用大于二分值的长度记为1,否则记为0,求最短路,如果到某个点的距离超过k,则需要增加答案,继续二分。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define inc(i,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 1001
 7 #define INF 0x3fffffff
 8 using namespace std;
 9 
10 inline int read(){
11     char ch=getchar(); int f=1,x=0;
12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
13     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
14     return f*x;
15 }
16 struct e{int t,w,y,n;}; e es[maxn*20]; int ess,g[maxn];
17 void pe(int f,int t,int w){
18     es[++ess]=(e){t,0,w,g[f]}; g[f]=ess; es[++ess]=(e){f,0,w,g[t]}; g[t]=ess;
19 }
20 bool inq[maxn]; int d[maxn],n,m,k,ans; queue<int>q;
21 bool spfa(){
22     while(!q.empty())q.pop(); memset(inq,0,sizeof(inq)); inc(i,1,n)d[i]=INF;
23     inq[1]=1; q.push(1); d[1]=0;
24     while(!q.empty()){
25         int x=q.front(); q.pop(); inq[x]=0;
26         for(int i=g[x];i;i=es[i].n)if(d[es[i].t]>d[x]+es[i].w){
27             d[es[i].t]=d[x]+es[i].w; if(!inq[es[i].t])inq[es[i].t]=1,q.push(es[i].t);
28         }
29     }
30     if(d[n]>k)return 0;else return 1;
31 }
32 bool check(int x){
33     inc(i,1,ess)if(es[i].y<=x)es[i].w=0;else es[i].w=1;
34     return spfa();
35 }
36 int main(){
37     n=read(); m=read(); k=read(); int l=0,r=0; ans=-1;
38     inc(i,1,m){int a=read(),b=read(),c=read(); pe(a,b,c); r=max(r,c);}
39     while(l<=r){
40         int mid=(l+r)>>1; if(check(mid))ans=mid,r=mid-1;else l=mid+1;
41     }
42     printf("%d",ans); return 0;
43 }

 

20160811

posted @ 2016-08-15 07:01  YuanZiming  阅读(394)  评论(0编辑  收藏  举报