[USACO08JAN]电话线Telephone Lines 洛谷P1948
来源:互联网 发布:马赛克复原软件 编辑:程序博客网 时间:2024/05/16 18:47
洛谷P1948
关键信息整理:给出一个有n个点的图,要求连接一些端点,使得终点和起点连通且第k-1长的路尽可能短。
解题思路:一看到第k-1长的路尽可能的短就想到二分答案,那么如何控制第k-1长的路呢?用sort肯定是不现实的,耗时耗空间。
不妨正好借二分答案,把大于答案长度的路设置成1,小于等于的设置成0,跑一个SPFA,因为可以连接无数个,这是个可行的方案。
然后就贴源代码了,这道题一开始的转化比较难,确定方向是二分答案后一切都变得美好了~
#include<iostream>#include<cstdio>#include<queue>#include<cstring>#include<cstdlib>using namespace std;/*const&int*/const int maxconn=100001;const int maxpow=10001;int ans;int totpow,totcon,freex;/*链式前向星*/struct ll{ int to; int nxt; int truevalue;//真正的长度 int spfavalue;//spfa时的01 }edge[maxconn];int head[maxpow],cnt=0;/*二分答案*/int l,r;#define mid ((l+r)>>1)//这里要注意位运算的优先度,反正多加括号不会错 /*SPFA*/queue<int> spfa;int quehead;bool exist[maxpow];int way[maxpow];/*init*/void setValue(){ for(int i=1;i<=totpow;++i) way[i]=100001;//memset不靠谱,这是上次做题时的血泪教训 for(int i=1;i<=totpow;++i) { for(int j=head[i];j!=-1;j=edge[j].nxt) { if(edge[j].truevalue<=mid)/*因为是判断答案是否可行,因此小于mid的直接变成0*/ { edge[j].spfavalue=0; } else { edge[j].spfavalue=1; } } }}/*链式前向星*/void addEdge(int x,int y,int value){ edge[++cnt].nxt=head[x]; edge[cnt].to=y; edge[cnt].truevalue=value; head[x]=cnt;}/*二分答案*/bool check(){ if(way[totpow]<=freex) { return 1; } else { return 0; }}/*SPFA*/void SPFA(){ /*正常的SPFA 中间的nowpay<=freex剪枝可以忽略不计*/ spfa.push(1); way[1]=0; int will,nowpay; while(spfa.empty()==0) { quehead=spfa.front(); spfa.pop(); exist[quehead]=0; for(int i=head[quehead];i!=-1;i=edge[i].nxt) { will=edge[i].to; nowpay=way[quehead]+edge[i].spfavalue; if(way[will]>nowpay&&nowpay<=freex) { way[will]=nowpay; if(exist[will]==0) { spfa.push(will); exist[will]=1; } } } }}int main(){ memset(head,-1,sizeof(head));//别问我为什么这里有memset l=0;r=-1; scanf("%d%d%d",&totpow,&totcon,&freex); int x,y,far; for(int i=1;i<=totcon;++i)//链式前向星储存 { scanf("%d%d%d",&x,&y,&far); addEdge(x,y,far); addEdge(y,x,far); r=max(r,far); } ans=-1; while(l<=r)//二分答案搜索 { setValue();//预处理spfavalue SPFA();//spfa if(check())//判断答案是否可行 { ans=mid; r=mid-1; } else { l=mid+1; } } printf("%d\n",ans); return 0;}
阅读全文
1 0
- [USACO08JAN]电话线Telephone Lines 洛谷P1948
- 洛谷P1948 [USACO08JAN]电话线Telephone Lines
- luogu P1948 [USACO08JAN]电话线Telephone Lines
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines【NOIP模拟笨笨的电话线】
- POJ3662,洛谷1948 [USACO08JAN]电话线Telephone Lines
- 洛谷 1948 [USACO08JAN]电话线Telephone Lines
- 二分查找+spfa(洛谷1948 [USACO08JAN]电话线Telephone Lines)
- 【USACO08JAN】洛谷1948 Telephone Lines
- [Usaco08Jan&luogu1948] Telephone Lines
- [Usaco2007 Jan]Telephone Lines架设电话线
- 1614: [Usaco2007 Jan]Telephone Lines架设电话线
- [BZOJ1614][Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ1614: [Usaco2007 Jan]Telephone Lines架设电话线
- [BZOJ1614][Usaco2007 Jan]Telephone Lines架设电话线
- bzoj1614【Usaco2007 Jan】Telephone Lines 架设电话线
- [Usaco2007 Jan]Telephone Lines架设电话线
- 1614: [Usaco2007 Jan]Telephone Lines架设电话线
- bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线
- 深入理解JAVA集合系列三:HashMap的死循环解读
- 在Docker中搭建Oracle数据库,并使用PL/SQL Developer链接
- 那些善良的人,一定要看。或许可以帮助你幸免于难
- Python 2.7.x 和 Python 3.x 的主要区别
- TP5自动验证机制
- [USACO08JAN]电话线Telephone Lines 洛谷P1948
- 初探oracle高级队列锁V$LOCK
- Spring Data Redis(sdr)-----序列化
- KLEE error reports
- ECharts 去掉地图(map)的指示图(visualMap)
- 深入理解JAVA集合系列二:ConcurrentHashMap源码解读
- solr历史版本
- 面试题3:数组中重复的数字
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字