二分+最短路
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu
Description
多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人。该市周围分布着N(1<=N<=1000)根据1……n顺序编号的废弃的电话线杆,任意两根线杆之间没有电话线连接,一共有p(1<=p<=10000)对电话杆可以拉电话线。其他的由于地震使得无法连接。
第i对电线杆的两个端点分别是ai,bi,它们的距离为li(1<=li<=1000000)。数据中每对(ai,bi)只出现一次。编号为1的电话杆已经接入了全国的电话网络,整个市的电话线全都连到了编号N的电话线杆上。也就是说,笨笨的任务仅仅是找一条将1号和N号电线杆连起来的路径,其余的电话杆并不一定要连入电话网络。
电信公司决定支援灾区免费为此市连接k对由笨笨指定的电话线杆,对于此外的那些电话线,需要为它们付费,总费用决定于其中最长的电话线的长度(每根电话线仅连接一对电话线杆)。如果需要连接的电话线杆不超过k对,那么支出为0.
请你计算一下,将电话线引导震中市最少需要在电话线上花多少钱?
Input
输入文件的第一行包含三个数字n,p,k;
第二行到第p+1行,每行分别都为三个整数ai,bi,li。
Output
一个整数,表示该项工程的最小支出,如果不可能完成则输出-1.
Sample Input
5 7 1 1 2 5 3 1 4 2 4 8 3 2 3 5 2 9 3 4 7 4 5 6
Sample Output
4
//挺有意思的一道题,要使第 k+1 边的值越小越好。想不到啊,spfa还能这么用,二分还能这么用
79ms
1 #include <stdio.h> 2 #include <string.h> 3 4 #define MAXN 1005 5 6 struct Edge{ 7 int v,w; 8 int next; 9 }edge[30005]; 10 int headlist[MAXN]; 11 12 int n,p,k,bian=0; 13 14 void join(int a,int b,int c) 15 { 16 bian++; 17 edge[bian].v=b; 18 edge[bian].w=c; 19 edge[bian].next=headlist[a]; 20 headlist[a]=bian; 21 } 22 23 int Q[1000]; 24 int vis[MAXN]; 25 int dis[MAXN];//大于limit的最少有多少个 26 int spfa(int limit) 27 { 28 for (int i=1;i<=n;i++) 29 dis[i]=10000000;//kanknkkkkkkkkkkkkk 30 memset(vis,0,sizeof(vis)); 31 32 Q[0]=1; 33 int l=0,r=1; 34 dis[1]=0,vis[1]=1; 35 while (l!=r) 36 { 37 int now=Q[l++]; 38 if (l==1000) l=0; 39 vis[now]=0; 40 int i=headlist[now]; 41 int mm=dis[now]; 42 while (i) 43 { 44 if (edge[i].w>limit) mm=dis[now]+1; 45 else mm=dis[now]; 46 if (mm<dis[edge[i].v]) 47 { 48 dis[edge[i].v]=mm; 49 if (vis[edge[i].v]==0) 50 { 51 Q[r++]=edge[i].v; 52 if (r==1000) r=0; 53 vis[edge[i].v]=1; 54 } 55 } 56 i=edge[i].next; 57 } 58 } 59 if (dis[n]<=k) return 1;// 60 return 0; 61 } 62 63 int main() 64 { 65 scanf("%d%d%d",&n,&p,&k); 66 int a,b,c; 67 for (int i=1;i<=p;i++) 68 { 69 scanf("%d%d%d",&a,&b,&c); 70 join(a,b,c); 71 join(b,a,c); 72 } 73 int l=0,r=1000000,ans=-1; 74 while (l<=r) 75 { 76 int mid=(l+r)/2; 77 if (spfa(mid)) 78 { 79 ans=mid;//记录后,看能不能有更小的值符合条件 80 r=mid-1; 81 } 82 else l=mid+1;//不能的话,只能看有没更大的了 83 } 84 printf("%d\n",ans); 85 return 0; 86 }
时间: 2024-10-25 03:24:23