[USACO08JAN]电话线Telephone Lines 洛谷P1948
2017-06-01 22:20
489 查看
洛谷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; }
相关文章推荐
- 洛谷P1948 [USACO08JAN]电话线Telephone Lines
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines
- 洛谷 P1948 [USACO08JAN]电话线Telephone Lines【NOIP模拟笨笨的电话线】
- 洛谷P1948 [USACO08JAN]电话线Telephone Lines
- 洛谷 1948 [USACO08JAN]电话线Telephone Lines
- POJ3662,洛谷1948 [USACO08JAN]电话线Telephone Lines
- 二分查找+spfa(洛谷1948 [USACO08JAN]电话线Telephone Lines) 4000
- [USACO08JAN]电话线Telephone Lines
- USACO 08 JAN 电话线Telephone Lines(二分法在图论题中的应用)
- luogu P1948 [USACO08JAN]电话线Telephone Lines
- [USACO08JAN]电话线Telephone Lines
- 洛谷P1948 [USACO08JAN]电话线Telephone Lines
- bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线【二分+spfa】
- [Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ1614: [Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ1614 [Usaco2007 Jan]Telephone Lines架设电话线 二分/魔性剪枝/最小边长连通
- [Usaco2007 Jan]Telephone Lines架设电话线[二分答案+最短路思想]
- BZOJ_1614_ [Usaco2007_Jan]_Telephone_Lines_架设电话线_(二分+最短路_Dijkstra/Spfa)
- 【bzoj1614】[Usaco2007 Jan]Telephone Lines架设电话线
- BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线