題意:
給你一些點 讓你求1-N的最短路 某個點能被訪問前提是這個點的所有前繼點都必須被訪問過 但是這個是可以同時進(jìn)行的
做法:
很像最大權(quán)閉合子圖之類的 結(jié)果說白了就是個變種最短路。。N^2 dijkstra水過。。
(一開始點數(shù)組開了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;
}