cy1131158493 @ 2020-10-27 23:09:31
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 10010, M = 50010 * 2,INF = 1000000010; //为啥这里INF = 2000000010就会wa掉两个样例呀???
int h[N],e[M],ne[M],w[M],f[M],idx;
int price[N];
void add(int a,int b,int c)
{
e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx ++;
}
int dist[N],q[M * 10];
bool st[N];
int n,m,k;
bool check(int mid)
{
int hh = 0, tt = 0;
memset(st,false,sizeof st);
for(int i = 0; i <= n; i ++) dist[i] = INF;
dist[1] = 0;
q[0] = 1;
while(hh <= tt)
{
int t = q[hh ++];
st[t] = false;
for(int i = h[t]; ~ i; i = ne[i])
{
int j = e[i];
if(price[j] <= mid && dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
if(! st[j])
{
st[j] = true;
q[++ tt] = j;
}
}
}
}
if(dist[n] > k || dist[n] >= INF / 2) return false;
// spfa 在判断是否可达的时候,不能直接使用INF判断,会出错
return true;
}
// bool check(int mid)
// {
// for(int i = 0; i < idx; i ++)
// if(w[i] > mid) f[i] = INF;
// else f[i] = w[i];
// return spfa();
// }
int main()
{
scanf("%d%d%d",&n,&m,&k);
int l = 0, r = 0;
memset(h,-1,sizeof h);
for(int i = 1; i <= n; i ++)
{
scanf("%d",&price[i]);
r = max(r,price[i]);
}
int t = r + 1;
r = t;
for(int i = 1; i <= m ; i ++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
while(l < r)
{
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
if(r == t) puts("AFK");
else printf("%d",r);
}
by Belarus @ 2020-10-27 23:12:58
@cy1131158493 因为可能会爆int,所以一般会设置成INT_MAX/2左右
by 小恐 @ 2020-10-27 23:14:20
@cy1131158493 因为
dist[t] + w[i]
有可能会爆int,然后你就WA了
by donghanwen1225 @ 2020-10-27 23:14:48
if(dist[n] > k || dist[n] >= INF / 2) return false;
// spfa 在判断是否可达的时候,不能直接使用INF判断,会出错
直接用INF判断的话,因为dist[n]被初始化为INF,那么不论如何这个if都会成立
by cy1131158493 @ 2020-10-27 23:17:17
@小恐 是的大佬,我刚刚意识到了这个问题,谢谢~
by cy1131158493 @ 2020-10-27 23:18:09
@Belarus 谢谢大佬,如果我设置成了2000000000在spfa中,dist[t] + w[i]就会溢出hhh,是我傻逼了
by cy1131158493 @ 2020-10-27 23:19:04
@donghanwen1225 可能会存在1和n不连通,但是n号点被其他点更新了,所以就不能直接用INF来判断,我是这样想的。