hdu3873带节点保护的最短路

来源:互联网 发布:淘宝拍图片用什么相机 编辑:程序博客网 时间:2024/06/18 17:12


题意:有一个图,如果有其他顶点保护着它,则它不能到达。

思路:到达某一点的时间一定是起点到达的最短路和它的保护限制的最大值。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const long long oo=99999999999999LL;const int mn=3300;const int mm=77000;int ver[mm],next[mm],cost[mm],vver[mm],nnext[mm];int head[mn],vis[mn],q[mn],num[mn],first[mn],f[mn];long long dis[mn];int edge,m,n,cnt;void addedge(int u,int v,int c){    ver[edge]=v,cost[edge]=c,next[edge]=head[u],head[u]=edge++;}void addedge2(int u,int v){    vver[cnt]=v,num[v]++,nnext[cnt]=first[u],first[u]=cnt++;}void Dij(){    int minp=1,i,v;    dis[1]=0;    f[1]=0;    for(int k=1;k<n;k++)    {        vis[minp]=1;//cout<<"minp="<<minp<<endl;        for(i=first[minp];i>=0;i=nnext[i])        {            //cout<<"i="<<i<<endl;            num[v=vver[i]]--;            if(dis[minp]>f[v])  f[v]=dis[minp];        }        for(i=head[minp];i>=0;i=next[i])        {            if(dis[v=ver[i]]>dis[minp]+cost[i])                dis[v]=dis[minp]+cost[i];        }        for(i=1;i<=n;i++)            dis[i]=dis[i]>f[i]?dis[i]:f[i];        minp=0;        for(i=2;i<=n;i++)            if(!vis[i]&&num[i]==0)            {                if(dis[i]<dis[minp])    minp=i;            }    }}int main(){    int t,cas=0,i,j,a,b,w;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        edge=0;cnt=0;        memset(head,-1,sizeof(head));        memset(first,-1,sizeof(first));        memset(num,0,sizeof(num));        memset(vis,0,sizeof(vis));        memset(f,0,sizeof(f));        memset(dis,1e4,sizeof(dis));        for(i=0;i<m;i++)        {            scanf("%d%d%d",&a,&b,&w);            addedge(a,b,w);        }        for(i=1;i<=n;i++)        {            scanf("%d",&a);            for(j=1;j<=a;j++)            {                scanf("%d",&b);                addedge2(b,i);            }        }        Dij();        printf("%d\n",dis[n]);    }    return 0;}