题意:
给你一些点 让你求1-N的最短路 某个点能被访问前提是这个点的所有前继点都必须被访问过 但是这个是可以同时进行的
做法:
很像最大权闭合子图之类的 结果说白了就是个变种最短路。。N^2 dijkstra水过。。
(一开始点数组开了1000 wa到死)
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define n 3005
#define m 300005
int vtx[m],w[m],ne[m],L[n],tot;
long long d[n],e[n];
int cnt[n],N,M;
vector<int> list[n];
bool vis[n];
inline void Ins(int u,int v,int cost)
{
vtx[++tot]=v;w[tot]=cost;ne[tot]=L[u];L[u]=tot;
}
inline long long dijkstra()
{
memset(d,127,sizeof(d));
memset(vis,0,sizeof(vis));
d[1]=0;
for (int i=1;i<N;++i)
{
int k=0;
long long dist=1LL<<60;
for (int j=1;j<=N;++j)
if (!vis[j]&&!cnt[j]&&max(d[j],e[j])<dist) k=j,dist=max(d[j],e[j]);
vis[k]=1,d[k]=max(d[k],e[k]);
for (int j=0;j<list[k].size();++j)
e[list[k][j]]=max(e[list[k][j]],d[k]),--cnt[list[k][j]];
for (int p=L[k],v=vtx[p];p;v=vtx[p=ne[p]])
d[v]=min(d[v],d[k]+w[p]);
}
return max(d[N],e[N]);
}
int main()
{
int u,v,w;
scanf("%d%d",&N,&M);
for (int i=0;i<M;++i)
scanf("%d%d%d",&u,&v,&w),Ins(u,v,w);
for (int i=1,j;i<=N;++i)
for (scanf("%d",&j);j--;)
scanf("%d",&v),++cnt[i],list[v].push_back(i);
cout<<dijkstra()<<endl;
return 0;
}