hdu 3873 Invade the Mars (有限制条件的最短路。。)
题意:n个点的图。。。每个点可能被若干其他点保护。。。被保护的意思是。。。如果想访问某个点。。那么必须先访问保护该点的所有点。。。问从点1到点n的最小代价。。
思路:。。一开始写了spfa。。。然后一脸懵逼。。。因为我第一次访问某个点的时候无法保证距离是最短的。。。所以还是上dij吧。。。
然后dij写得比较少。。。不是很熟练。。参考了这篇题解参考题解
思路倒是不难想,我在写spfa的时候也是这样想法,然后试图记录路径递归来搞。。。。。然而并不可以2333
也是第一次遇到带限制条件的最短路。。。还是多积累吧。。。
哦对了。。。权值比较大。。。要记得开long long
/* ***********************************************
Author :111qqz
Created Time :2016年07月15日 星期五 00时32分14秒
File Name :code/hdu/3873.cpp
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < long long ,int >
#define MP make_pair
using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=3E3+7;
const int M=7E4+7;
int n,m;
int cnt;
int head[N];
int in[N]; //in[i]表示点i被几个点保护。。。
vector <int>prec[N];
LL d[N];
bool vis[N];
LL maxt[N];
struct Edge
{
int v;
LL w;
int nxt;
}edge[M];
void init()
{
ms(head,-1);
ms(in,0);
cnt = 0 ;
for ( int i = 1 ; i <= n ; i++) prec[i].clear();
}
void addedge( int u,int v,int w)
{
edge[cnt].v = v;
edge[cnt].w = w;
edge[cnt].nxt = head[u];
head[u]=cnt;
cnt++;
}
LL dij( int s)
{
priority_queue<pi,vector<pi>,greater<pi> >q;
ms(d,0x3f);
ms(vis,false);
ms(maxt,0);
d[s] = 0 ;
q.push(make_pair(d[s],s));
while (!q.empty())
{
pi cur = q.top();
q.pop();
int u = cur.sec;
if (vis[u]) continue;
vis[u] = true;
int siz = prec[u].size();
for ( int i = 0 ; i < siz ; i++)
{
int v = prec[u][i];
in[v]--;
maxt[v] = max(maxt[v],d[u]);
if (d[v]!=inf&&!in[v])
{
d[v] = max(d[v],maxt[v]);
q.push(make_pair(d[v],v));
}
}
for ( int i = head[u] ; i != -1 ; i = edge[i].nxt)
{
int v = edge[i].v;
LL w = edge[i].w;
if (d[v]>d[u]+w)
{
d[v] = d[u] + w;
if (!in[v]) q.push(make_pair(d[v],v));
}
}
}
return d[n];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("code/in.txt","r",stdin);
#endif
int T;
cin>>T;
while (T--)
{
scanf("%d%d",&n,&m);
init();
for ( int i = 1 ; i <= m ; i++)
{
int u,v;
LL w;
scanf("%d%d%lld",&u,&v,&w);
addedge(u,v,w);
}
for ( int i = 1 ; i <= n ; i++)
{
int x;
scanf("%d",&x);
in[i] = x;
while (x--)
{
int y ;
scanf("%d",&y);
prec[y].push_back(i);
}
}
LL ans = dij(1);
printf("%lld\n",ans);
}
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
return 0;
}