dijstra的变形,对于每一个点,到达这个点的时间就是原图上到达该点的最短路和到达他的卫星中的最大值。。。维护一下入度就行了。。。。注意题目中的边是单向的。。。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 3005
#define maxm 20000005
#define eps 1e-10
#define mod 1000000007
#define INF 1e17
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
struct Edge
{
int v;
LL c;
Edge *next;
}pool[maxm], *edges, *H[maxn], *h[maxn];
struct node
{
int u;
LL d;
bool operator < (const node& b) const {
return d > b.d;
}
}now, tmp;
priority_queue<node> q;
LL dist[maxn], most[maxn];
int vis[maxn], in[maxn];
int n, m;
void addedges(int u, int v)
{
edges->v = v;
edges->next = h[u];
h[u] = edges++;
}
void Addedges(int u, int v, LL c)
{
edges->v = v;
edges->c = c;
edges->next = H[u];
H[u] = edges++;
}
void init(void)
{
edges = pool;
memset(h, 0, sizeof h);
memset(H, 0, sizeof H);
memset(in, 0, sizeof in);
memset(vis, 0, sizeof vis);
memset(most, 0, sizeof most);
}
void read(void)
{
int a, b;
LL c;
scanf("%d%d", &n, &m);
while(m--) {
scanf("%d%d%I64d", &a, &b, &c);
Addedges(a, b, c);
}
for(int i = 1; i <= n; i++) {
scanf("%d", &m);
while(m--) {
scanf("%d", &a);
addedges(a, i);
in[i]++;
}
}
}
LL dijstra(int s)
{
for(int i = 0; i <= n; i++) dist[i] = INF;
tmp.u = s, tmp.d = 0, dist[s] = 0;
q.push(tmp);
while(!q.empty()) {
now = q.top(), q.pop();
int u = now.u, d = now.d;
if(vis[u]) continue;
vis[u] = 1;
for(Edge *e = H[u]; e; e = e->next) {
if(dist[e->v] > dist[u] + e->c) {
dist[e->v] = dist[u] + e->c;
if(!in[e->v]) {
dist[e->v] = max(dist[e->v], most[e->v]);
tmp.u = e->v, tmp.d = dist[e->v];
q.push(tmp);
}
}
}
for(Edge *e = h[u]; e; e = e->next) {
most[e->v] = max(dist[u], most[e->v]);
in[e->v]--;
if(!in[e->v] && dist[e->v] != INF) {
dist[e->v] = max(dist[e->v], most[e->v]);
tmp.u = e->v, tmp.d = dist[e->v];
q.push(tmp);
}
}
}
return dist[n];
}
void work(void)
{
printf("%I64d\n", dijstra(1));
}
int main(void)
{
int _;
while(scanf("%d", &_)!=EOF) {
while(_--) {
init();
read();
work();
}
}
return 0;
}