题意:给一个图,定义两点间的距离为路径上最大的边权,可以将路径上不多于k条边的权值变为0,求两点间最小距离
二分答案,判断时只要将大于当前二分值的边记为1,否则记为0,做一遍spfa,判断dist是否大于k即可
无向边数忘记乘2卡了半天T_T
spfa队列数组要开得比结点数多
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 #define maxn 1010 6 #define maxe 20100 7 struct node{ 8 int to,next,weight; 9 }Edge[maxe]; 10 int n,p,k; 11 int cnt=0,mxl=0; 12 int last[maxn],q[maxn*10],dist[maxn]; 13 bool inq[maxn]; 14 int read(){ 15 int x=0,f=1; 16 char ch=getchar(); 17 while (ch<'0'||ch>'9') { 18 if (ch=='-') f=-1; 19 ch=getchar(); 20 } 21 while (ch>='0'&&ch<='9'){ 22 x=x*10+ch-'0'; 23 ch=getchar(); 24 } 25 return x*f; 26 } 27 void insert(int u,int v,int w){ 28 Edge[++cnt].to=v; 29 Edge[cnt].next=last[u]; 30 last[u]=cnt; 31 Edge[cnt].weight=w; 32 } 33 bool ok(int cost){ 34 memset(inq,0,sizeof(inq)); 35 memset(dist,127/3,sizeof(dist)); 36 memset(q,0,sizeof(q)); 37 int head=0,tail=1,now,len,i; 38 inq[1]=1;q[head]=1;dist[1]=0; 39 while (head<tail){ 40 now=q[head++]; 41 len=0; 42 i=last[now]; 43 while (i){ 44 len=Edge[i].weight>cost?dist[now]+1:dist[now]; 45 if (len<dist[Edge[i].to]){ 46 dist[Edge[i].to]=len; 47 if (!inq[Edge[i].to]){ 48 q[tail++]=Edge[i].to; 49 inq[Edge[i].to]=1; 50 } 51 } 52 i=Edge[i].next; 53 } 54 inq[now]=0; 55 } 56 return dist[n]>k?0:1; 57 } 58 int main(){ 59 n=read();p=read();k=read(); 60 int u,v,w; 61 memset(last,0,sizeof(last)); 62 for (int i=1;i<=p;i++){ 63 u=read(),v=read(),w=read(); 64 insert(u,v,w); 65 insert(v,u,w); 66 mxl=max(mxl,w); 67 } 68 int l=0,r=mxl,mid; 69 int ans=-1; 70 while (l<=r){ 71 mid=(l+r)>>1; 72 if (ok(mid)){ 73 ans=mid;r=mid-1; 74 } 75 else l=mid+1; 76 } 77 printf("%d ",ans); 78 return 0; 79 }