In my opinion, people are divided into two categories: some live in the future while others — in the past. Should it be explained what category did I belong? The mystery I hunted for a half of my life, finally was taking shape. Good Magician didn't know where Dragon hid. But he knew that bandit dens in some cities of the kingdom were controlled by people from the Dragon's gang. For each city he gave me a reliable information, whether Dragon controlled that city or not.
I was staring on the map of Fairy Kingdom trying to understand where to go now. There were n cities in the Kingdom, connected by mroads, with the length of the j-th road equal to wj. I guessed that Dragon hid in one of two cities controlled by his gang with the shortest path between them. First of all, the traffic of Blue Tea was the highest between them, and secondly, in case of emergency it was possible to move quickly from one of the cities to the other. All that remained was just to find such pair of cities.
The first line contains two integers separated by a space: n and m (2 ≤ n ≤ 105, 1 ≤ m ≤ 105) — the number of cities in Fairy Kingdom and the number of roads between them, correspondingly.
The second line contains n integers separated by spaces. On the i-th position the number 1 is written, if the i-th city is under control of Dragon's gang; otherwise the number 0 is written there.
The next m lines contain three integers each, separated by spaces: ai, bi, wi (1 ≤ ai < bi ≤ n, 1 ≤ wi ≤ 109) — the numbers of cities connected by a road and the length of this road. The cities are numbered from 1. Each pair of cities is presented at most once.
In the first line output a single integer — the length of the shortest path between cities where Dragon presumably hides.
In the second line output two integers separated by a space — the numbers of these cities.
If there are several possible answers, output any of them. If no two cities controlled by Dragon's people have a path between them, output «No luck at all» without quotes.
4 4 1 0 0 1 1 2 1 1 3 2 2 4 3 3 4 1
3 4 1
7 9 1 0 1 1 0 0 1 1 2 5 1 4 100 2 3 5 2 5 4 2 6 4 3 7 100 4 5 2 6 7 2 5 6 3
7 4 7
2 1 0 0 1 2 1
No luck at all
题意:
城市有两种属性(0/1),找最近的两个属性为1的城市,输出最短路长度与起点终点。
题解:
SPFA变形,单源最短路转化为,所有点到某个1之间的最短路,然后枚举中间边,找合法解。
解法:
SPFA,将所有1点同时初始化为0,同时进栈进行松弛,最终可求出每一点到最近的1的距离及最近的1是哪个点。然后遍历所有边,若一条边两边都是1,则路径合法;若两边都是0,且两边最近的1不同点,则路径合法;若一边0一边1,且两边最近的1不同点,则路径合法。最后将所有合法路径取最小值即为答案。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,a,n) for (int i=a;i=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector VI;
typedef long long ll;
typedef pair PII;
const ll inf=9e18;
const ll mod=1000000007;
const int maxn=1e5+100;
int head[maxn];
struct edge
{
int from,to,next;
ll w;
}e[maxn*2]; //
int tol=0;
void add(int u,int v,ll w)
{
e[++tol].to=v,e[tol].from=u,e[tol].next=head[u],e[tol].w=w,head[u]=tol;
}
int a[maxn];
ll d[maxn];
int pre[maxn];
int q[maxn],inq[maxn];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
rep(i,1,n+1) scanf("%d",&a[i]);
while(m--)
{
int u,v;
ll w;
scanf("%d%d%I64d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
int front=0,rear=0;
rep(i,1,n+1) d[i]=inf;
rep(i,1,n+1)
{
if(a[i])
{
q[rear++]=i,inq[i]=1,d[i]=0,pre[i]=i;
}
}
while(front!=rear)
{
int u=q[front++];
if(front>=maxn) front=0;
inq[u]=0;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
ll w=e[i].w;
if(d[u]+w=maxn) rear=0;
}
}
}
ll ans=inf;
int u,v;
for(int i=0;i<=tol;i+=2)
{
int u1=e[i].from,v1=e[i].to;
if(a[u1]&&a[v1])
{
if(e[i].w=inf) puts("No luck at all");
else
{
printf("%I64d\n%d %d\n",ans,u,v);
}
return 0;
}