开始做的时候,模模糊糊知道点思想,但老是wa,我开始是,当更新到一个点的时候 如果通过这个点使得某些点没约束了,就更新dis=max(dis,l) l是这个点的最短路(相对起点)
但老是wa,后来想了下,要用一个数组记录需要到这个点,需要到达所有点时间的最大值,每次循环,用这个更新下dis才比较科学,改了下 AC了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
const int inf=99999999;
using namespace std;
int T,n,m,a,b,l,vi[3010],nu,ct[3010],dis[3010],f[3010];
struct node
{
int y,l;
node(int a,int b):y(a),l(b){}
friend bool operator < (node a,node b)
{
return a.l>b.l;
}
};
vector<node>vt[3010];
vector<int>st[3010];
int DIJ()
{
priority_queue<node>q;
fill(dis,dis+n+1,inf);
dis[1]=0;
q.push(node(1,0));
memset(vi,0,sizeof(vi));
memset(f,0,sizeof(f));
while(!q.empty())
{
int s=q.top().y,l=q.top().l;
q.pop();
if(vi[s])continue;
vi[s]=1;
if(s==n)return l;
for(int i=0;i<st[s].size();i++)
{
int y=st[s][i];
if(vi[y])continue;
--ct[y];
f[y]=max(f[y],dis[s]);
}
for(int i=0;i<vt[s].size();i++)
{
int y=vt[s][i].y,ll=vt[s][i].l;
if(dis[y]>l+ll)
dis[y]=l+ll;
}
for(int i=1;i<=n;i++)
{
if(vi[i])continue;
dis[i]=max(dis[i],f[i]);
if(ct[i]==0)
q.push(node(i,dis[i]));
}
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){vt[i].clear();st[i].clear();}
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&a,&b,&l);
vt[a].push_back(node(b,l));
}
for(int i=1;i<=n;i++)
{
scanf("%d",&nu);
ct[i]=nu;
for(int j=1;j<=nu;j++)
{
int tmp;
scanf("%d",&tmp);
st[tmp].push_back(i);
}
}
printf("%d\n",DIJ());
}
return 0;
}