2017.10.19 大陆争霸 思考记录

来源:互联网 发布:多核单片机 编辑:程序博客网 时间:2024/06/11 05:59

一上来想到拓扑分层最短路,但需要多源最短路。。

这题考查的是对dij的理解

dij只能跑最短路每次都找极值点进行一次拓展,同时不能有负边权

所以一次需要确定  两个值都确定的一个点所以扩展的条件有两个,一个是最短路不被更新,一个是保护的点不再更新

所以就相当于在保护的点中选一个更新


spfa不能维护两个值。。


码:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>using namespace std;#define N 3005#define M 70005int tot,hou[M],xia[N],zhong[M],v[M],d[N],jk[N],i,j,n,rd[N],m,a,b,c;bool vis[N];queue<int>js[N];void jia(int a,int b,int c){++tot,hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b,v[tot]=c;}void dij(){for(i=2;i<=n;i++)d[i]=1000000007;for(i=1;i<=n;i++){int o=0,minn=1000000007;for(j=1;j<=n;j++)if(minn>max(d[j],jk[j])&&vis[j]==0&&rd[j]==0){minn=max(d[j],jk[j]);o=j;}if(o==0)break;vis[o]=1;while(!js[o].empty()){int nd=js[o].front();js[o].pop();if(vis[nd]==1)continue;jk[nd]=max(jk[nd],minn);rd[nd]--;}for(j=xia[o];j!=-1;j=hou[j]){int nd=zhong[j];if(vis[nd]==1)continue;d[nd]=min(d[nd],minn+v[j]);}}}int main(){memset(xia,-1,sizeof(xia));scanf("%d%d",&n,&m);for(i=1;i<=m;i++){scanf("%d%d%d",&a,&b,&c);jia(a,b,c);}for(i=1;i<=n;i++){scanf("%d",&rd[i]);for(j=1;j<=rd[i];j++){scanf("%d",&b);js[b].push(i);}}dij();printf("%d",max(d[n],jk[n]));}


原创粉丝点击