题目大意
给定N个点P条边的无向图,官方提供k条免费边。求如何去掉免费边,使剩下的边之中最大的边权最小,输出最大的边权
这题…最大的最小,很容易想到二分…而且这些边一定构成了最短路。
啊啊啊啊啊,我的代码在洛谷上过了,但是在poj上死活不过=。=
#include <cstdio>
#include <queue>
#include <iostream>
#include <algorithm>
#include <cstring>
const int maxn = 100100;
int n,m,begin,end,k,au[maxn],av[maxn],aw[maxn],diss[maxn],ans,r;
struct edge{
int u,v,w,next,ww;
} e[maxn];
int a[maxn],num;
inline void addedge(int u,int v,int w){
num++;
e[num].u = u;
e[num].v = v;
e[num].w = w;
e[num].next = a[u];
a[u] = num;
}
int dis[maxn],vis[maxn];
struct st{
int n,w;
bool operator <(const st &a) const{
return a.w < w;
}
};
std::priority_queue<st> q;
void dijkstra(int l){
memset(vis,0,sizeof(vis));
for(int i = 1;i <= n;i++)
dis[i] = 0x7fffffff;
dis[begin] = 0;
q.push((st){begin,0});
while(!q.empty()){
int x = q.top().n;
q.pop();
if (vis[x])continue;
vis[x] = 1;
for(int i = a[x];i;i = e[i].next){
int y = e[i].v;
if(e[i].w > l)
e[i].ww = 1;
else
e[i].ww = 0;
if (dis[x] + e[i].ww < dis[y]){
dis[y] = dis[x] + e[i].ww;
q.push((st){y,dis[y]});
}
}
}
}
bool check(int l) {
dijkstra(l);
if(dis[n] > k) return false;
else return true;
}
int main(){
scanf("%d %d %d",&n,&m,&k);
for(int i = 1;i <= m;i++){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
r = r < w ? w : r;
}
begin = 1;
end = n;
int l = 1;
while(l <= r) {
int mid = (l+r) >> 1;
if(check(mid)) {
ans = mid;
r = mid-1;
}
else
l = mid+1;
}
if(ans == 0) {
printf("-1");
return 0;
}
printf("%d\n",ans);
}