【bzoj1614】【Usaco2007 Jan】Telephone Lines架设电话线 (spfa+二分)题解&代码
2016-05-17 10:31
357 查看
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=1614
题解:
刚开始没看清题,以为是spfa中记录路径,后来发现花费只是多余花费中最大的花费,那么我们就可以二分这个最大花费,将路径中大于这个花费的边全部交给电力公司去做,看它是否能做完。
代码:
http://www.lydsy.com/JudgeOnline/problem.php?id=1614
题解:
刚开始没看清题,以为是spfa中记录路径,后来发现花费只是多余花费中最大的花费,那么我们就可以二分这个最大花费,将路径中大于这个花费的边全部交给电力公司去做,看它是否能做完。
代码:
#include<iostream> #include<algorithm> #include<stdio.h> #include<queue> #define maxn (10005) using namespace std; struct node{ int next;int v;int w; }edge[maxn*2]; int n,m,k,dis[1005],head[1005],tot,vis[1005]; queue<int>q; void add(int u,int v,int d) { tot++; edge[tot].v=v; edge[tot].w=d; edge[tot].next=head[u]; head[u]=tot; } void init() { for (int i=1;i<=n;i++) { dis[i]=9999999; vis[i]=0; } } int bfs(int x) { init(); while(!q.empty())q.pop(); q.push(1); vis[1]=1; dis[1]=0; while(!q.empty()) { int now=q.front();q.pop();vis[now]=0; for (int i=head[now];i!=0;i=edge[i].next) { int v=edge[i].v; int d=edge[i].w>x?1:0; //大于x为1小于为0 if (dis[v]>dis[now]+d) { dis[v]=dis[now]+d; if (vis[v]==0) { q.push(v); vis[v]=1; } } } } return dis ; //dis表示当最大花费为x时,最少有多少条边需要交给电力公司 } int main() { scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=m;i++) { int x,y,d; scanf("%d%d%d",&x,&y,&d); add(x,y,d); add(y,x,d); } if (bfs(-1)==9999999) { printf("-1\n"); return 0; } int l=0,r=1000000; int ans=0; while(l<=r) { int mid=(l+r)/2; //cout<<l<<' '<<r<<endl; if (bfs(mid)<=k) ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); }
相关文章推荐
- Win7下搭建python开发环境图文教程(安装Python、pip、解释器)
- Qt布局相关因素汇总
- Java 并发编程:volatile的使用及其原理解析
- java aop实用小案例
- C++程序设计必知:常引用、常对象和对象的常成员
- php字符串函数
- C# 爬虫 100个明星贴吧
- java反射的简单应用
- java中Random(long seed)方法与rRandom()方法的使用产生随机数
- php数据类型
- Eclipse如何创建properties文件
- RxJava---使用场景
- QT QCompleter的简单使用
- java 设置代理ip
- php 递归创建及删除目录
- php echo和print
- Python中 sys.argv 用法
- php 递归创建目录
- C / C++ 输入输出缓存处理
- UpdateLayeredWindow代码