最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

电话线

IT圈 admin 36浏览 0评论

电话线

电话线

二分答案+最短路

问题描述

​ Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务。于是,FJ必须为此向电信公司支付一定的费用。
FJ的农场周围分布着N根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连。一共P对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接。
第i对电话线杆的两个端点分别为A_i、B_i,它们间的距离为L_i 。数据中保证每对{A_i,B_i}最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络,整个农场的电话线全都连到了编号为N的电话线杆上。也就是说,FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话网络。
经过谈判,电信公司最终同意免费为FJ连结K对由FJ指定的电话线杆。对于此外的那些电话线,FJ需要为它们付的费用,等于其中最长的电话线的长度(每根电话线仅连结一对电话线杆)。如果需要连结的电话线杆不超过K对,那么FJ的总支出为0。
请你计算一下,FJ最少需要在电话线上花多少钱。

输入格式

第一行输入3个用空格隔开的整数:N、P、以及K
以下P行中,第i行为3个用空格隔开的整数:A_i、B_i、L_i。

输出格式

输出一个整数,为FJ在这项工程上的最小支出。
如果任务不可能完成,输出-1。

思路

FJ要在所有方案中选择电话线花费最大的最小值(除开电力公司已经支付的电话线)。二分答案:二分FJ在电话线上的花费。

怎么判断当前二分的答案mid合不合理:

电力公司要支付的电线用二维数组G记录。如果某根电话线的长度>=mid,那么电力公司就会支付,G[i][j]=G[j][i]=1,表示电力公司要支付这根电话线;否则就赋值为0,表示不支付。G数组跑一遍最短路,就是电力公司至少应该支付的电话线的数量。如果支付数量>K,说明这个答案不合理,增大下界;反则减小上界。

代码

#include<iostream>
#include<cstdio>
#include<queue>
#define N 50000
#define Inf 1e9
using namespace std;
int n,p,k;
int NextM[N],LastM[N],LenM[N],EndM[N],cntM;
int Next[N],Last[N],Len[N],End[N],dis[N],cnt;
bool used[N],usedM[N];
struct node{int id,len;bool operator<(const node &a)const{return len>a.len;}
};
//建图:电话线的布局
void InsM(int x,int y,int l){EndM[++cntM]=y;LenM[cntM]=l;NextM[cntM]=LastM[x];LastM[x]=cntM;
}
//建图:电力公司需要支付的电话线
void InsG(int x,int y,int l){End[++cnt]=y;Len[cnt]=l;Next[cnt]=Last[x];Last[x]=cnt;
}
void dijkstra(int s){for(int i=1;i<N;i++)dis[i]=Inf;priority_queue<node>q;q.push((node){s,0}),dis[s]=0;while(!q.empty()){int u=q.top().id;q.pop();if(used[u])continue;used[u]=true;for(int i=Last[u];i;i=Next[i]){int v=End[i];if(!used[v] && dis[v]>dis[u]+Len[i]){dis[v]=dis[u]+Len[i];q.push((node){v,dis[v]});}}}
}
//初始化
void CleanG(){for(int i=1;i<N;i++){usedM[i]=false,used[i]=false;Next[i]=false,Last[i]=false,End[i]=false;}
}
//判断二分答案是否合理
bool Get(int mid){cnt=0;CleanG();for(int i=1;i<=n;i++){usedM[i]=true;for(int j=LastM[i];j;j=NextM[j])if(!usedM[EndM[j]]){//注意:由于是边存储,所以即便花费<=mid也要加边;如果用二维数组存图就不需要if(LenM[j]>mid)InsG(i,EndM[j],1),InsG(EndM[j],i,1);else InsG(i,EndM[j],0),InsG(EndM[j],i,0);}}dijkstra(1);if(dis[n]<=k)return true;else return false;
}
int main(){int L=0,R=0,Max=0;scanf("%d%d%d",&n,&p,&k);for(int i=1;i<=p;i++){int a,b,l;scanf("%d%d%d",&a,&b,&l);R=max(R,l),Max=R;InsM(a,b,l),InsM(b,a,l);}while(L<=R){int mid=((L+R)>>1);if(Get(mid))R=mid-1;else L=mid+1;}if(L>Max)puts("-1");else printf("%d",L);return 0;
}

总结

1.不是所有的最短路的题目都只考最短路

2.注意初始化

3.题目没有说明是有向图,那就是无向图

电话线

电话线

二分答案+最短路

问题描述

​ Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务。于是,FJ必须为此向电信公司支付一定的费用。
FJ的农场周围分布着N根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连。一共P对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接。
第i对电话线杆的两个端点分别为A_i、B_i,它们间的距离为L_i 。数据中保证每对{A_i,B_i}最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络,整个农场的电话线全都连到了编号为N的电话线杆上。也就是说,FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话网络。
经过谈判,电信公司最终同意免费为FJ连结K对由FJ指定的电话线杆。对于此外的那些电话线,FJ需要为它们付的费用,等于其中最长的电话线的长度(每根电话线仅连结一对电话线杆)。如果需要连结的电话线杆不超过K对,那么FJ的总支出为0。
请你计算一下,FJ最少需要在电话线上花多少钱。

输入格式

第一行输入3个用空格隔开的整数:N、P、以及K
以下P行中,第i行为3个用空格隔开的整数:A_i、B_i、L_i。

输出格式

输出一个整数,为FJ在这项工程上的最小支出。
如果任务不可能完成,输出-1。

思路

FJ要在所有方案中选择电话线花费最大的最小值(除开电力公司已经支付的电话线)。二分答案:二分FJ在电话线上的花费。

怎么判断当前二分的答案mid合不合理:

电力公司要支付的电线用二维数组G记录。如果某根电话线的长度>=mid,那么电力公司就会支付,G[i][j]=G[j][i]=1,表示电力公司要支付这根电话线;否则就赋值为0,表示不支付。G数组跑一遍最短路,就是电力公司至少应该支付的电话线的数量。如果支付数量>K,说明这个答案不合理,增大下界;反则减小上界。

代码

#include<iostream>
#include<cstdio>
#include<queue>
#define N 50000
#define Inf 1e9
using namespace std;
int n,p,k;
int NextM[N],LastM[N],LenM[N],EndM[N],cntM;
int Next[N],Last[N],Len[N],End[N],dis[N],cnt;
bool used[N],usedM[N];
struct node{int id,len;bool operator<(const node &a)const{return len>a.len;}
};
//建图:电话线的布局
void InsM(int x,int y,int l){EndM[++cntM]=y;LenM[cntM]=l;NextM[cntM]=LastM[x];LastM[x]=cntM;
}
//建图:电力公司需要支付的电话线
void InsG(int x,int y,int l){End[++cnt]=y;Len[cnt]=l;Next[cnt]=Last[x];Last[x]=cnt;
}
void dijkstra(int s){for(int i=1;i<N;i++)dis[i]=Inf;priority_queue<node>q;q.push((node){s,0}),dis[s]=0;while(!q.empty()){int u=q.top().id;q.pop();if(used[u])continue;used[u]=true;for(int i=Last[u];i;i=Next[i]){int v=End[i];if(!used[v] && dis[v]>dis[u]+Len[i]){dis[v]=dis[u]+Len[i];q.push((node){v,dis[v]});}}}
}
//初始化
void CleanG(){for(int i=1;i<N;i++){usedM[i]=false,used[i]=false;Next[i]=false,Last[i]=false,End[i]=false;}
}
//判断二分答案是否合理
bool Get(int mid){cnt=0;CleanG();for(int i=1;i<=n;i++){usedM[i]=true;for(int j=LastM[i];j;j=NextM[j])if(!usedM[EndM[j]]){//注意:由于是边存储,所以即便花费<=mid也要加边;如果用二维数组存图就不需要if(LenM[j]>mid)InsG(i,EndM[j],1),InsG(EndM[j],i,1);else InsG(i,EndM[j],0),InsG(EndM[j],i,0);}}dijkstra(1);if(dis[n]<=k)return true;else return false;
}
int main(){int L=0,R=0,Max=0;scanf("%d%d%d",&n,&p,&k);for(int i=1;i<=p;i++){int a,b,l;scanf("%d%d%d",&a,&b,&l);R=max(R,l),Max=R;InsM(a,b,l),InsM(b,a,l);}while(L<=R){int mid=((L+R)>>1);if(Get(mid))R=mid-1;else L=mid+1;}if(L>Max)puts("-1");else printf("%d",L);return 0;
}

总结

1.不是所有的最短路的题目都只考最短路

2.注意初始化

3.题目没有说明是有向图,那就是无向图

Error[2]: Trying to access array offset on value of type int, File: /www/wwwroot/www.usbmi.com/xiunophp/xiunophp.min.php, Line: 54
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 1095, humandate(1717080346)
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 662, well_thread_format(array(26))
File: /www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm, Line: 249, well_thread_find_asc(array(4) , 4)
File: /www/wwwroot/www.usbmi.com/tmp/route_read.php, Line: 204, include(/www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm)
File: /www/wwwroot/www.usbmi.com/tmp/index.inc.php, Line: 129, include(/www/wwwroot/www.usbmi.com/tmp/route_read.php)
File: /www/wwwroot/www.usbmi.com/index.php, Line: 29, include(/www/wwwroot/www.usbmi.com/tmp/index.inc.php)
Error[2]: Trying to access array offset on value of type int, File: /www/wwwroot/www.usbmi.com/xiunophp/xiunophp.min.php, Line: 54
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 1096, humandate(1717080346)
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 662, well_thread_format(array(27))
File: /www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm, Line: 249, well_thread_find_asc(array(4) , 4)
File: /www/wwwroot/www.usbmi.com/tmp/route_read.php, Line: 204, include(/www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm)
File: /www/wwwroot/www.usbmi.com/tmp/index.inc.php, Line: 129, include(/www/wwwroot/www.usbmi.com/tmp/route_read.php)
File: /www/wwwroot/www.usbmi.com/index.php, Line: 29, include(/www/wwwroot/www.usbmi.com/tmp/index.inc.php)
Error[2]: Trying to access array offset on value of type int, File: /www/wwwroot/www.usbmi.com/xiunophp/xiunophp.min.php, Line: 54
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 1095, humandate(1730661540)
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 662, well_thread_format(array(26))
File: /www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm, Line: 249, well_thread_find_asc(array(4) , 4)
File: /www/wwwroot/www.usbmi.com/tmp/route_read.php, Line: 204, include(/www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm)
File: /www/wwwroot/www.usbmi.com/tmp/index.inc.php, Line: 129, include(/www/wwwroot/www.usbmi.com/tmp/route_read.php)
File: /www/wwwroot/www.usbmi.com/index.php, Line: 29, include(/www/wwwroot/www.usbmi.com/tmp/index.inc.php)
Error[2]: Trying to access array offset on value of type int, File: /www/wwwroot/www.usbmi.com/xiunophp/xiunophp.min.php, Line: 54
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 1096, humandate(1730661540)
File: /www/wwwroot/www.usbmi.com/tmp/model_thread.func.php, Line: 662, well_thread_format(array(27))
File: /www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm, Line: 249, well_thread_find_asc(array(4) , 4)
File: /www/wwwroot/www.usbmi.com/tmp/route_read.php, Line: 204, include(/www/wwwroot/www.usbmi.com/tmp/view_template_d8_htm_read.htm)
File: /www/wwwroot/www.usbmi.com/tmp/index.inc.php, Line: 129, include(/www/wwwroot/www.usbmi.com/tmp/route_read.php)
File: /www/wwwroot/www.usbmi.com/index.php, Line: 29, include(/www/wwwroot/www.usbmi.com/tmp/index.inc.php)
发布评论

评论列表 (0)

  1. 暂无评论