2014
03-02

# Dolphin

Dolphins are marine mammals that are closely related to whales and porpoises. They might have some kind of the biggest brains in the water, but are dolphins really smart? Some scientists say that they use their big brains to stay warm in the sea, rather than for lots of thinking. Obviously those scientists don’t think dolphins are smart.
We know that the brain is made up of two types of cells � neurons and glia. Neurons do the thinking, while glia do things like keeping the brain warm to help the neurons. After looking at how dolphins’ brains are put together, they claim that dolphins have lots of glia and not many neurons.
In order to find out how smart the dolphins are, we throw one of them into a maze we’ve just created, to see how long it’ll take the dolphin to get out.
The maze consists of nodes and bidirectional edges connecting them.
The dolphin needs power to swim, so we place exactly one fish at each node for him to enjoy.
The dolphin is not interested in eating the same kind of fish more than once, but he can’t resist any food if it’s just in front to him! As a result, the dolphin decided to PLAN a route before going, so that it will not REACH any kind of fish more than once.
Given the information above, can you tell me the minimum time that the dolphin needs to get out?

The first line consists of an integer T, indicating the number of test cases.
The first line of each case consists of four integers N, M, S and E, indicating the number of nodes, the number of edges, the starting node and destination.
Each of the next M lines consists of three integers U, V, C, indicating that there is an edge with length C between node U and V. It will take a dolphin C time to pass this edge.
The next line consists of N integers. Ki indicates the label of which kind fishes i-th node has.

The first line consists of an integer T, indicating the number of test cases.
The first line of each case consists of four integers N, M, S and E, indicating the number of nodes, the number of edges, the starting node and destination.
Each of the next M lines consists of three integers U, V, C, indicating that there is an edge with length C between node U and V. It will take a dolphin C time to pass this edge.
The next line consists of N integers. Ki indicates the label of which kind fishes i-th node has.

2
2 1 0 1
0 1 1
0 0
4 4 0 3
0 1 1
1 3 1
0 2 2
2 3 2
0 0 1 2

-1
4

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<ctime>
using namespace std;
const int MAX=1005;
const int inf=1<<26;
struct node
{
int v,w,next;
}g[MAX*100];
int dis[MAX],fa[MAX],pre[MAX];
int flag[MAX];
bool pos[MAX],found;
{
}
void spfa(int s,int t,int k)
{
int i,u,v;
queue<int>que;
for(i=0;i<=n;i++)
dis[i]=inf;
if(k)
memset(pre,-1,sizeof(pre));
dis[s]=0;
memset(vis1,0,sizeof(vis1));
vis1[s]=1;
que.push(s);
while(!que.empty())
{
u=que.front();
que.pop();
vis1[u]=0;
{
v=g[i].v;
if(vis2[kind[v]])
continue;
//if(kind[v]==kind[t])
//continue;
//if(kind[v]==kind[s]&&v!=s)
//continue;
if(dis[v]>dis[u]+g[i].w)
{
dis[v]=dis[u]+g[i].w;
pre[v]=u;
if(!vis1[v])
{
vis1[v]=1;
que.push(v);
}
}
}
}
}
bool check()
{
for(int i=0;i<MAX;i++)
if(flag[i]>1)
return false;
return true;
}
bool dfs(int u,int now,int limit,int t)
{
if(now>limit)
return false;
if(u==t)
return true;
spfa(u,t,0);
if(now+dis[t]>limit)
return false;
int i,v;
{
v=g[i].v;
if(vis2[kind[v]])
continue;
vis2[kind[v]]=1;
if(dfs(v,now+g[i].w,limit,t))
return true;
vis2[kind[v]]=0;
}
return false;
}
void solve(int s,int t,int sum)
{
int l=1,r=sum,ans=-1,mid;
while(l<=r)
{
mid=(l+r)>>1;
memset(vis2,0,sizeof(vis2));
vis2[kind[s]]=1;
if(dfs(s,0,mid,t))
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
printf("%d\n",ans);
}
inline int nextInt()
{
int res = 0; char ch;
bool neg = false;
while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
if (ch == '-') neg = true;
else res = ch - '0';
while (ch = getchar(), ch >= '0' && ch <= '9') res = res * 10 + ch - '0';
if (neg) res = - res;
return res;
}
int main()
{
int i,j,k,T,s,t,sum=0;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&m,&s,&t);
e=0;
while(m--)
{
//scanf("%d%d%d",&i,&j,&k);
i=nextInt(); j=nextInt(); k=nextInt();
sum+=k;
}
for(i=0;i<n;i++)
{
//scanf("%d",&kind[i]);
kind[i]=nextInt();
}
if(s==t)
{
puts("0");
continue;
}
memset(vis2,0,sizeof(vis2));
vis2[kind[t]]=1;
spfa(t,s,1);
memset(flag,0,sizeof(flag));
if(pre[s]==-1)
{
puts("-1");
continue;
}
for(i=s;i!=-1;i=pre[i])
{
flag[kind[i]]++;
}
if(check())
{
printf("%d\n",dis[s]);
continue;
}
solve(s,t,sum);
}
return 0;
}